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

📄 ftp.c

📁 harvest是一个下载html网页得机器人
💻 C
📖 第 1 页 / 共 5 页
字号:
{#ifndef ENABLE_IPV6  /*****************************************************************   *   * IPv4-only code section   */  struct in_addr in;  struct hostent * answer;#ifdef HAVE_INET_NTOA_R  char ntoa_buf[64];#endif  /* The array size trick below is to make this a large chunk of memory     suitably 8-byte aligned on 64-bit platforms. This was thoughtfully     suggested by Philip Gladstone. */  long bigbuf[9000 / sizeof(long)];#if defined(HAVE_INET_ADDR)  in_addr_t address;# if defined(HAVE_GETHOSTBYADDR_R)  int h_errnop;# endif  char *hostent_buf = (char *)bigbuf; /* get a char * to the buffer */  address = inet_addr(newhost);# ifdef HAVE_GETHOSTBYADDR_R#  ifdef HAVE_GETHOSTBYADDR_R_5  /* AIX, Digital Unix (OSF1, Tru64) style:     extern int gethostbyaddr_r(char *addr, size_t len, int type,     struct hostent *htent, struct hostent_data *ht_data); */  /* Fred Noz helped me try this out, now it at least compiles! */  /* Bjorn Reese (November 28 2001):     The Tru64 man page on gethostbyaddr_r() says that     the hostent struct must be filled with zeroes before the call to     gethostbyaddr_r().      ... as must be struct hostent_data Craig Markwardt 19 Sep 2002. */  memset(hostent_buf, 0, sizeof(struct hostent)+sizeof(struct hostent_data));  if(gethostbyaddr_r((char *) &address,                     sizeof(address), AF_INET,                     (struct hostent *)hostent_buf,                     (struct hostent_data *)(hostent_buf + sizeof(*answer))))    answer=NULL;  else    answer=(struct hostent *)hostent_buf;                           #  endif#  ifdef HAVE_GETHOSTBYADDR_R_7  /* Solaris and IRIX */  answer = gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,                           (struct hostent *)bigbuf,                           hostent_buf + sizeof(*answer),                           sizeof(bigbuf) - sizeof(*answer),                           &h_errnop);#  endif#  ifdef HAVE_GETHOSTBYADDR_R_8  /* Linux style */  if(gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,                     (struct hostent *)hostent_buf,                     hostent_buf + sizeof(*answer),                     sizeof(bigbuf) - sizeof(*answer),                     &answer,                     &h_errnop))    answer=NULL; /* error */#  endif        # else  (void)hostent_buf; /* avoid compiler warning */  answer = gethostbyaddr((char *) &address, sizeof(address), AF_INET);# endif#else  answer = NULL;#endif  (void) memcpy(&in.s_addr, addr, sizeof (Curl_ipconnect));  infof(conn->data, "Connecting to %s (%s) port %u\n",        answer?answer->h_name:newhost,#if defined(HAVE_INET_NTOA_R)        inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)),#else        inet_ntoa(in),#endif        port);#else  /*****************************************************************   *   * IPv6-only code section   */  char hbuf[NI_MAXHOST]; /* ~1KB */  char nbuf[NI_MAXHOST]; /* ~1KB */  char sbuf[NI_MAXSERV]; /* around 32 */#ifdef NI_WITHSCOPEID  const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;#else  const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;#endif  (void)port; /* prevent compiler warning */  if (getnameinfo(addr->ai_addr, addr->ai_addrlen,                  nbuf, sizeof(nbuf), sbuf, sizeof(sbuf), niflags)) {    snprintf(nbuf, sizeof(nbuf), "?");    snprintf(sbuf, sizeof(sbuf), "?");  }          if (getnameinfo(addr->ai_addr, addr->ai_addrlen,                  hbuf, sizeof(hbuf), NULL, 0, 0)) {    infof(conn->data, "Connecting to %s (%s) port %s\n", nbuf, newhost, sbuf);  }  else {    infof(conn->data, "Connecting to %s (%s) port %s\n", hbuf, nbuf, sbuf);  }#endif}/*********************************************************************** * * ftp_use_port() * * Send the proper PORT command. PORT is the ftp client's way of telling the * server that *WE* open a port that we listen on an awaits the server to * connect to. This is the opposite of PASV. */staticCURLcode ftp_use_port(struct connectdata *conn){  struct SessionHandle *data=conn->data;  int portsock=-1;  ssize_t nread;  int ftpcode; /* receive FTP response codes in this */  CURLcode result;#ifdef ENABLE_IPV6  /******************************************************************   *   * Here's a piece of IPv6-specific code coming up   *   */  struct addrinfo hints, *res, *ai;  struct sockaddr_storage ss;  socklen_t sslen;  char hbuf[NI_MAXHOST];  struct sockaddr *sa=(struct sockaddr *)&ss;#ifdef NI_WITHSCOPEID  const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;#else  const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;#endif  unsigned char *ap;  unsigned char *pp;  char portmsgbuf[4096], tmp[4096];  const char *mode[] = { "EPRT", "LPRT", "PORT", NULL };  char **modep;  /*   * we should use Curl_if2ip?  given pickiness of recent ftpd,   * I believe we should use the same address as the control connection.   */  sslen = sizeof(ss);  if (getsockname(conn->firstsocket, (struct sockaddr *)&ss, &sslen) < 0)    return CURLE_FTP_PORT_FAILED;    if (getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL, 0,                  niflags))    return CURLE_FTP_PORT_FAILED;  memset(&hints, 0, sizeof(hints));  hints.ai_family = sa->sa_family;  /*hints.ai_family = ss.ss_family;    this way can be used if sockaddr_storage is properly defined, as glibc     2.1.X doesn't do*/  hints.ai_socktype = SOCK_STREAM;  hints.ai_flags = AI_PASSIVE;  if (getaddrinfo(hbuf, (char *)"0", &hints, &res))    return CURLE_FTP_PORT_FAILED;    portsock = -1;  for (ai = res; ai; ai = ai->ai_next) {    portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);    if (portsock < 0)      continue;    if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {      sclose(portsock);      portsock = -1;      continue;    }          if (listen(portsock, 1) < 0) {      sclose(portsock);      portsock = -1;      continue;    }        break;  }  freeaddrinfo(res);  if (portsock < 0) {    failf(data, "%s", strerror(errno));    return CURLE_FTP_PORT_FAILED;  }  sslen = sizeof(ss);  if (getsockname(portsock, sa, &sslen) < 0) {    failf(data, "%s", strerror(errno));    return CURLE_FTP_PORT_FAILED;  }  for (modep = (char **)(data->set.ftp_use_eprt?&mode[0]:&mode[2]);       modep && *modep; modep++) {    int lprtaf, eprtaf;    int alen=0, plen=0;        switch (sa->sa_family) {    case AF_INET:      ap = (unsigned char *)&((struct sockaddr_in *)&ss)->sin_addr;      alen = sizeof(((struct sockaddr_in *)&ss)->sin_addr);      pp = (unsigned char *)&((struct sockaddr_in *)&ss)->sin_port;      plen = sizeof(((struct sockaddr_in *)&ss)->sin_port);      lprtaf = 4;      eprtaf = 1;      break;    case AF_INET6:      ap = (unsigned char *)&((struct sockaddr_in6 *)&ss)->sin6_addr;      alen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_addr);      pp = (unsigned char *)&((struct sockaddr_in6 *)&ss)->sin6_port;      plen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_port);      lprtaf = 6;      eprtaf = 2;      break;    default:      ap = pp = NULL;      lprtaf = eprtaf = -1;      break;    }    if (strcmp(*modep, "EPRT") == 0) {      if (eprtaf < 0)        continue;      if (getnameinfo((struct sockaddr *)&ss, sslen,                      portmsgbuf, sizeof(portmsgbuf), tmp, sizeof(tmp), niflags))        continue;      /* do not transmit IPv6 scope identifier to the wire */      if (sa->sa_family == AF_INET6) {        char *q = strchr(portmsgbuf, '%');          if (q)            *q = '\0';      }      result = Curl_ftpsendf(conn, "%s |%d|%s|%s|", *modep, eprtaf,                             portmsgbuf, tmp);      if(result)        return result;    } else if (strcmp(*modep, "LPRT") == 0 ||               strcmp(*modep, "PORT") == 0) {      int i;            if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0)        continue;      if (strcmp(*modep, "PORT") == 0 && sa->sa_family != AF_INET)        continue;      portmsgbuf[0] = '\0';      if (strcmp(*modep, "LPRT") == 0) {        snprintf(tmp, sizeof(tmp), "%d,%d", lprtaf, alen);        if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >=            sizeof(portmsgbuf)) {          continue;        }      }      for (i = 0; i < alen; i++) {        if (portmsgbuf[0])          snprintf(tmp, sizeof(tmp), ",%u", ap[i]);        else          snprintf(tmp, sizeof(tmp), "%u", ap[i]);                if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >=            sizeof(portmsgbuf)) {          continue;        }      }            if (strcmp(*modep, "LPRT") == 0) {        snprintf(tmp, sizeof(tmp), ",%d", plen);                if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf))          continue;      }      for (i = 0; i < plen; i++) {        snprintf(tmp, sizeof(tmp), ",%u", pp[i]);                if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >=            sizeof(portmsgbuf)) {          continue;        }      }            result = Curl_ftpsendf(conn, "%s %s", *modep, portmsgbuf);      if(result)        return result;    }        result = Curl_GetFTPResponse(&nread, conn, &ftpcode);    if(result)      return result;        if (ftpcode != 200) {      continue;    }    else      break;  }    if (!*modep) {    sclose(portsock);    failf(data, "PORT command attempts failed");    return CURLE_FTP_PORT_FAILED;  }  /* we set the secondary socket variable to this for now, it     is only so that the cleanup function will close it in case     we fail before the true secondary stuff is made */  conn->secondarysocket = portsock;  #else  /******************************************************************   *   * Here's a piece of IPv4-specific code coming up   *   */  struct sockaddr_in sa;  struct Curl_dns_entry *h=NULL;  unsigned short porttouse;  char myhost[256] = "";  bool sa_filled_in = FALSE;  if(data->set.ftpport) {    in_addr_t in;    int rc;    /* First check if the given name is an IP address */    in=inet_addr(data->set.ftpport);    if((in == CURL_INADDR_NONE) &&       Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {      rc = Curl_resolv(conn, myhost, 0, &h);      if(rc == 1)        rc = Curl_wait_for_resolv(conn, &h);    }    else {      int len = strlen(data->set.ftpport);      if(len>1) {        rc = Curl_resolv(conn, data->set.ftpport, 0, &h);        if(rc == 1)          rc = Curl_wait_for_resolv(conn, &h);      }      if(h)        strcpy(myhost, data->set.ftpport); /* buffer overflow risk */    }  }  if(! *myhost) {    /* pick a suitable default here */    socklen_t sslen;        sslen = sizeof(sa);    if (getsockname(conn->firstsocket, (struct sockaddr *)&sa, &sslen) < 0) {      failf(data, "getsockname() failed");      return CURLE_FTP_PORT_FAILED;    }    sa_filled_in = TRUE; /* the sa struct is filled in */  }  if(h)    /* when we return from here, we can forget about this */    Curl_resolv_unlock(data, h);  if ( h || sa_filled_in) {    if( (portsock = socket(AF_INET, SOCK_STREAM, 0)) >= 0 ) {      int size;            /* we set the secondary socket variable to this for now, it         is only so that the cleanup function will close it in case         we fail before the true secondary stuff is made */      conn->secondarysocket = portsock;      if(!sa_filled_in) {        memset((char *)&sa, 0, sizeof(sa));        memcpy((char *)&sa.sin_addr,               h->addr->h_addr,               h->addr->h_length);        sa.sin_family = AF_INET;        sa.sin_addr.s_addr = INADDR_ANY;      }      sa.sin_port = 0;      size = sizeof(sa);            if(bind(portsock, (struct sockaddr *)&sa, size) >= 0) {        /* we succeeded to bind */        struct sockaddr_in add;        socklen_t socksize = sizeof(add);        if(getsockname(portsock, (struct sockaddr *) &add,                       &socksize)<0) {          failf(data, "getsockname() failed");          return CURLE_FTP_PORT_FAILED;        }        porttouse = ntohs(add.sin_port);                if ( listen(portsock, 1) < 0 ) {          failf(data, "listen(2) failed on socket");          return CURLE_FTP_PORT_FAILED;        }      }      else {        failf(data, "bind(2) failed on socket");        return CURLE_FTP_PORT_FAILED;      }    }    else {      failf(data, "socket(2) failed (%s)");      return CURLE_FTP_PORT_FAILED;

⌨️ 快捷键说明

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