Logo Search packages:      
Sourcecode: freetds version File versions

int tds_connect ( TDSSOCKET *  tds,
TDSCONNECTINFO *  connect_info 
)

Do a connection to socket

Parameters:
tds connection structure. This should be a non-connected connection. If the function fail connection is deleted
connect_info info for connection
Returns:
TDS_FAIL or TDS_SUCCEED

Definition at line 199 of file login.c.

References tds_client_msg(), tds_connect(), tds_process_login_tokens(), tds_process_simple_query(), tds_quote_id(), tds_submit_query(), and tds_version().

Referenced by tds_connect().

{
      struct sockaddr_in sin;

      /* Jeff's hack - begin */
      unsigned long ioctl_blocking = 1;
      struct timeval selecttimeout;
      fd_set fds;
      int retval;
      time_t start, now;
      int connect_timeout = 0;
      int db_selected = 0;
      char version[256];
      char *str;
      int len;
      TDS_INT restype;

      FD_ZERO(&fds);

      /*
       * If a dump file has been specified, start logging
       */
      if (!tds_dstr_isempty(&connect_info->dump_file)) {
            tdsdump_open(connect_info->dump_file);
      }

      tds->connect_info = connect_info;

      tds->major_version = connect_info->major_version;
      tds->minor_version = connect_info->minor_version;
      tds->emul_little_endian = connect_info->emul_little_endian;
#ifdef WORDS_BIGENDIAN
      if (IS_TDS7_PLUS(tds)) {
            /* TDS 7/8 only supports little endian */
            tds->emul_little_endian = 1;
      }
#endif

      /* set up iconv */
      if (connect_info->client_charset) {
            tds_iconv_open(tds, connect_info->client_charset);
      }

      /* specified a date format? */
      /*
       * if (connect_info->date_fmt) {
       * tds->date_fmt=strdup(connect_info->date_fmt);
       * }
       */
      connect_timeout = connect_info->connect_timeout;

      /* Jeff's hack - begin */
      tds->timeout = (connect_timeout) ? connect_info->query_timeout : 0;
      tds->longquery_timeout = (connect_timeout) ? connect_info->longquery_timeout : 0;
      tds->longquery_func = connect_info->longquery_func;
      tds->longquery_param = connect_info->longquery_param;
      /* end */

      /* verify that ip_addr is not NULL */
      if (tds_dstr_isempty(&connect_info->ip_addr)) {
            tdsdump_log(TDS_DBG_ERROR, "%L IP address pointer is NULL\n");
            if (connect_info->server_name) {
                  tdsdump_log(TDS_DBG_ERROR, "%L Server %s not found!\n", connect_info->server_name);
            } else {
                  tdsdump_log(TDS_DBG_ERROR, "%L No server specified!\n");
            }
            tds_free_socket(tds);
            return TDS_FAIL;
      }
      sin.sin_addr.s_addr = inet_addr(connect_info->ip_addr);
      if (sin.sin_addr.s_addr == -1) {
            tdsdump_log(TDS_DBG_ERROR, "%L inet_addr() failed, IP = %s\n", connect_info->ip_addr);
            tds_free_socket(tds);
            return TDS_FAIL;
      }

      sin.sin_family = AF_INET;
      sin.sin_port = htons(connect_info->port);

      memcpy(tds->capabilities, connect_info->capabilities, TDS_MAX_CAPABILITY);


      retval = tds_version(tds, version);
      if (!retval)
            version[0] = '\0';

      tdsdump_log(TDS_DBG_INFO1, "%L Connecting addr %s port %d with TDS version %s\n", inet_ntoa(sin.sin_addr),
                ntohs(sin.sin_port), version);
      if ((tds->s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
            perror("socket");
            tds_free_socket(tds);
            return TDS_FAIL;
      }

      /* Jeff's hack *** START OF NEW CODE *** */
      if (connect_timeout) {
            start = time(NULL);
            ioctl_blocking = 1;     /* ~0; //TRUE; */
            if (IOCTLSOCKET(tds->s, FIONBIO, &ioctl_blocking) < 0) {
                  tds_free_socket(tds);
                  return TDS_FAIL;
            }
            retval = connect(tds->s, (struct sockaddr *) &sin, sizeof(sin));
            if (retval < 0 && errno == EINPROGRESS)
                  retval = 0;
            if (retval < 0) {
                  perror("src/tds/login.c: tds_connect (timed)");
                  tds_free_socket(tds);
                  return TDS_FAIL;
            }
            /* Select on writeability for connect_timeout */
            now = start;
            while ((retval == 0) && ((now - start) < connect_timeout)) {
                  FD_SET(tds->s, &fds);
                  selecttimeout.tv_sec = connect_timeout - (now - start);
                  selecttimeout.tv_usec = 0;
                  retval = select(tds->s + 1, NULL, &fds, NULL, &selecttimeout);
                  if (retval < 0 && errno == EINTR)
                        retval = 0;
                  now = time(NULL);
            }

            if ((now - start) >= connect_timeout) {
                  tds_client_msg(tds->tds_ctx, tds, 20009, 9, 0, 0, "Server is unavailable or does not exist.");
                  tds_free_socket(tds);
                  return TDS_FAIL;
            }
      } else if (connect(tds->s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
            char *message;

            if (asprintf(&message, "src/tds/login.c: tds_connect: %s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)) >= 0) {
                  perror(message);
                  free(message);
            }
            tds_client_msg(tds->tds_ctx, tds, 20009, 9, 0, 0, "Server is unavailable or does not exist.");
            tds_free_socket(tds);
            return TDS_FAIL;
      }
      /* END OF NEW CODE */

      if (IS_TDS7_PLUS(tds)) {
            tds->out_flag = 0x10;
            tds7_send_login(tds, connect_info);
            db_selected = 1;
      } else {
            tds->out_flag = 0x02;
            tds_send_login(tds, connect_info);
      }
      if (!tds_process_login_tokens(tds)) {
            tds_close_socket(tds);
            tds_client_msg(tds->tds_ctx, tds, 20014, 9, 0, 0, "Login incorrect.");
            tds_free_socket(tds);
            return TDS_FAIL;
      }

      if (connect_info->text_size || (!db_selected && !tds_dstr_isempty(&connect_info->database))) {
            len = 64 + tds_quote_id(tds, NULL, connect_info->database);
            str = (char*) malloc(len);
            str[0] = 0;
            if (connect_info->text_size) {
                  sprintf(str, "set textsize %d ", connect_info->text_size);
            }
            if (!db_selected && !tds_dstr_isempty(&connect_info->database)) {
                  strcat(str, "use ");
                  tds_quote_id(tds, strchr(str, 0), connect_info->database);
            }
            retval = tds_submit_query(tds, str);
            free(str);
            if (retval != TDS_SUCCEED) {
                  tds_free_socket(tds);
                  return TDS_FAIL;
            }

            if (tds_process_simple_query(tds, &restype) == TDS_FAIL || restype == TDS_CMD_FAIL) {
                  tds_free_socket(tds);
                  return TDS_FAIL;
            }
      }

      tds->connect_info = NULL;
      return TDS_SUCCEED;
}


Generated by  Doxygen 1.6.0   Back to index