Commit c9c7fcf4 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

Stephen Kick's interface fixes

parent 4dba5750
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -109,6 +109,9 @@ CURL *curl_easy_init(void)
    return NULL;

  data->interf = CURLI_EASY; /* mark it as an easy one */
  /* SAC */
  data->device = NULL;

  return data;
}

+172 −1
Original line number Diff line number Diff line
@@ -52,7 +52,6 @@

#include <errno.h>


#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
#include <time.h>
@@ -498,6 +497,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
  case CURLOPT_QUOTE:
    data->quote = va_arg(param, struct curl_slist *);
    break;
  case CURLOPT_INTERFACE:
    data->device = va_arg(param, char *);
    break;
  default:
    /* unknown tag and its companion, just ignore: */
    return CURLE_READ_ERROR; /* correct this */
@@ -1176,6 +1178,136 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
  conn->serv_addr.sin_family = conn->hp->h_addrtype;
  conn->serv_addr.sin_port = htons(data->port);

/* sck 8/31/2000 add support for specifing device to bind socket to */
/* #ifdef LINUX */
/* I am using this, but it may not work everywhere, only tested on RedHat 6.2 */
#ifdef HAVE_INET_NTOA

#ifndef INADDR_NONE
#define INADDR_NONE (unsigned long) ~0
#endif

  if (data->device && (strlen(data->device)<255)) {
    struct ifreq ifr;
    struct sockaddr_in sa;
    struct hostent *h=NULL;
    size_t size;
    unsigned short porttouse;
    char myhost[256] = "";
    unsigned long in;

    if(if2ip(data->device, myhost, sizeof(myhost))) {
      h = GetHost(data, myhost, hostent_buf, sizeof(hostent_buf));
    }
    else {
      if(strlen(data->device)>1) {
        h = GetHost(data, data->device, hostent_buf,
                    sizeof(hostent_buf));
      }
      if(h) {
        strcpy(myhost,data->device);
      }
    }

    if(! *myhost) {
      /* need to fix this
         h=GetHost(data,
         getmyhost(*myhost,sizeof(myhost)),
         hostent_buf,
         sizeof(hostent_buf));
      */
      printf("in here\n");
    }

    infof(data, "We connect from %s\n", myhost);

    if ( (in=inet_addr(myhost)) != INADDR_NONE ) {

      if ( h ) {
        memset((char *)&sa, 0, sizeof(sa));
        memcpy((char *)&sa.sin_addr,
               h->h_addr,
               h->h_length);
        sa.sin_family = AF_INET;
        sa.sin_addr.s_addr = in;
        sa.sin_port = 0; /* get any port */
	
        if( bind(data->firstsocket, (struct sockaddr *)&sa, sizeof(sa)) >= 0) {
          /* we succeeded to bind */
          struct sockaddr_in add;
	
          size = sizeof(add);
          if(getsockname(data->firstsocket, (struct sockaddr *) &add,
                         (int *)&size)<0) {
            failf(data, "getsockname() failed");
            return CURLE_HTTP_PORT_FAILED;
          }
        }
        else {
          switch(errno) {
          case EBADF:
            failf(data, "Invalid descriptor: %d", errno);
            break;
          case EINVAL:
            failf(data, "Invalid request: %d", errno);
            break;
          case EACCES:
            failf(data, "Address is protected, user not superuser: %d", errno);
            break;
          case ENOTSOCK:
            failf(data,
                  "Argument is a descriptor for a file, not a socket: %d",
                  errno);
            break;
          case EFAULT:
            failf(data, "Inaccessable memory error: %d", errno);
            break;
          case ENAMETOOLONG:
            failf(data, "Address too long: %d", errno);
            break;
          case ENOMEM:
            failf(data, "Insufficient kernel memory was available: %d", errno);
            break;
#if 0
          case EROFS:
            failf(data,
                  "Socket inode would reside on a read-only file system: %d",
                  errno);
            break;
          case ENOENT:
            failf(data, "File does not exist: %d", errno);
            break;
          case ENOTDIR:
            failf(data, "Component of path prefix is not a directory: %d",
                  errno);
            break;
          case ELOOP:
            failf(data,"Too many symbolic links encountered: %d",errno);
            break;
#endif
          default:
            failf(data,"errno %d\n");
          } /* end of switch */
	
          return CURLE_HTTP_PORT_FAILED;
        } /* end of else */
	
      } /* end of if  h */
      else {
	failf(data,"could't find my own IP address (%s)", myhost);
	return CURLE_HTTP_PORT_FAILED;
      }

    } /* end of inet_addr */

    else {
      failf(data, "could't find my own IP address (%s)", myhost);
      return CURLE_HTTP_PORT_FAILED;
    }

  } /* end of device selection support */
#endif  /* end of HAVE_INET_NTOA */

  if (connect(data->firstsocket,
              (struct sockaddr *) &(conn->serv_addr),
              sizeof(conn->serv_addr)
@@ -1186,11 +1318,50 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
    case ECONNREFUSED:
      failf(data, "Connection refused");
      break;
    case EFAULT:
      failf(data, "Invalid socket address: %d",errno);
      break;
    case EISCONN:
      failf(data, "Socket already connected: %d",errno);
      break;
    case ETIMEDOUT:
      failf(data, "Timeout while accepting connection, server busy: %d",errno);
      break;
    case ENETUNREACH:
      failf(data, "Network is unreachable: %d",errno);
      break;
    case EADDRINUSE:
      failf(data, "Local address already in use: %d",errno);
      break;
    case EINPROGRESS:
      failf(data, "Socket is nonblocking and connection can not be completed immediately: %d",errno);
      break;
    case EALREADY:
      failf(data, "Socket is nonblocking and a previous connection attempt not completed: %d",errno);
      break;
    case EAGAIN:
      failf(data, "No more free local ports: %d",errno);
      break;
    case EACCES:
    case EPERM:
      failf(data, "Attempt to connect to broadcast address without socket broadcast flag or local firewall rule violated: %d",errno);
      break;
#endif
#ifdef EINTR
    case EINTR:
      failf(data, "Connection timeouted");
      break;
#endif
#if 0
    case EAFNOSUPPORT:
      failf(data, "Incorrect address family: %d",errno);
      break;
    case ENOTSOCK:
      failf(data, "File descriptor is not a socket: %d",errno);
      break;
    case EBADF:
      failf(data, "File descriptor is not a valid index in descriptor table: %d",errno);
      break;
#endif
    default:
      failf(data, "Can't connect to server: %d", errno);
+1 −0
Original line number Diff line number Diff line
@@ -356,6 +356,7 @@ struct UrlData {
  char *useragent;   /* User-Agent string */

  char *ftpport; /* port to send with the PORT command */
  char *device;  /* Interface to use */

  /* function that stores the output:*/
  curl_write_callback fwrite;