~ubuntu-branches/ubuntu/trusty/erlang/trusty

« back to all changes in this revision

Viewing changes to lib/odbc/c_src/odbcserver.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Byrum
  • Date: 2011-05-05 15:48:43 UTC
  • mfrom: (3.5.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110505154843-0om6ekzg6m7ugj27
Tags: 1:14.b.2-dfsg-3ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to.
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.
  - debian/patches/series: Do what I meant, and enable build-options.patch
    instead.
* Additional changes:
  - Drop erlang-wx from -et
* Dropped Changes:
  - patches/pcre-crash.patch: CVE-2008-2371: outer level option with
    alternatives caused crash. (Applied Upstream)
  - fix for ssl certificate verification in newSSL: 
    ssl_cacertfile_fix.patch (Applied Upstream)
  - debian/patches/series: Enable native.patch again, to get stripped beam
    files and reduce the package size again. (build-options is what
    actually accomplished this)
  - Remove build-options.patch on advice from upstream and because it caused
    odd build failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * %CopyrightBegin%
3
 
 * 
4
 
 * Copyright Ericsson AB 1999-2009. All Rights Reserved.
5
 
 * 
 
3
 *
 
4
 * Copyright Ericsson AB 1999-2011. All Rights Reserved.
 
5
 *
6
6
 * The contents of this file are subject to the Erlang Public License,
7
7
 * Version 1.1, (the "License"); you may not use this file except in
8
8
 * compliance with the License. You should have received a copy of the
9
9
 * Erlang Public License along with this software. If not, it can be
10
10
 * retrieved online at http://www.erlang.org/.
11
 
 * 
 
11
 *
12
12
 * Software distributed under the License is distributed on an "AS IS"
13
13
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
 * the License for the specific language governing rights and limitations
15
15
 * under the License.
16
 
 * 
 
16
 *
17
17
 * %CopyrightEnd%
18
18
 *
19
19
 
59
59
   they are converted to string values.
60
60
 
61
61
   [?OPEN_CONNECTION, C_AutoCommitMode, C_TraceDriver, C_SrollableCursors,
62
 
   C_TupelRow, ConnectionStr]
 
62
   C_TupelRow, BinaryStrings, ConnectionStr]
63
63
   [?CLOSE_CONNECTION]               
64
64
   [?COMMIT_TRANSACTION, CommitMode]
65
65
   [?QUERY, SQLQuery]
76
76
   C_TraceDriver - ?ON | ?OFF
77
77
   C_SrollableCursors - ?ON | ?OFF
78
78
   C_TupelRow -  - ?ON | ?OFF
 
79
   BinaryStrings - ?ON | ?OFF
79
80
   ConnectionStr -  String
80
81
   CommitMode -  ?COMMIT | ?ROLLBACK
81
82
   SQLQuery  - String
88
89
   InOrOut = [ERL_ODBC_IN | ERL_ODBC_OUT | ERL_ODBC_INOUT]
89
90
   Datatype -  USER_INT | USER_SMALL_INT | {USER_DECIMAL, Precision, Scale} |
90
91
   {USER_NMERIC, Precision, Scale} | {USER_CHAR, Max} | {USER_VARCHAR, Max} |
91
 
   {USER_FLOAT, Precision} | USER_REAL | USER_DOUBLE
 
92
   {USER_WVARCHAR, Max} | {USER_FLOAT, Precision} | USER_REAL | USER_DOUBLE |
 
93
   USER_TIMESTAMP
92
94
   Scale - integer
93
95
   Precision - integer
94
96
   Max - integer
106
108
 
107
109
#if defined WIN32
108
110
#include <winsock2.h> 
109
 
/*  #include <ws2tcpip.h >  When we can support a newer c-compiler*/
110
111
#include <windows.h> 
 
112
#include <ws2tcpip.h >
111
113
#include <fcntl.h>
112
114
#include <sql.h>
113
115
#include <sqlext.h>
119
121
#include <sys/socket.h>
120
122
#include <sys/uio.h>
121
123
#include <netdb.h>
 
124
#include <netinet/in.h>
122
125
#endif
123
126
 
124
127
#include <limits.h>
172
175
                              db_state *state);
173
176
static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size,
174
177
                             SQLSMALLINT decimal_digits, db_state *state);
175
 
static Boolean decode_params(byte *buffer, int *index, param_array **params,
 
178
static Boolean decode_params(db_state *state, byte *buffer, int *index, param_array **params,
176
179
                          int i, int j);
177
180
 
178
181
/*------------- Erlang port communication functions ----------------------*/
377
380
    shutdown(socket, 2);
378
381
    close_socket(socket);
379
382
    clean_socket_lib();
380
 
    DO_EXIT(EXIT_SUCCESS);
 
383
    /* Exit will be done by suervisor thread */ 
381
384
}
382
385
 
383
386
/* Description: Calls the appropriate function to handle the database
432
435
    diagnos diagnos;
433
436
    byte *connStrIn; 
434
437
    int erl_auto_commit_mode, erl_trace_driver,
435
 
        use_srollable_cursors, tuple_row_state;
 
438
        use_srollable_cursors, tuple_row_state, binary_strings;
436
439
  
437
440
    erl_auto_commit_mode = args[0];
438
441
    erl_trace_driver = args[1];
439
442
    use_srollable_cursors = args[2];
440
443
    tuple_row_state = args[3];
441
 
    connStrIn = args + 4 * sizeof(byte);
 
444
    binary_strings = args[4];
 
445
    connStrIn = args + 5 * sizeof(byte);
442
446
 
443
447
    if(tuple_row_state == ON) {
444
 
        tuple_row(state) = TRUE;  
445
 
    } else {
446
 
        tuple_row(state) = FALSE;  
447
 
    }
448
 
  
 
448
            tuple_row(state) = TRUE;  
 
449
    } else {
 
450
            tuple_row(state) = FALSE;  
 
451
    }
 
452
    
 
453
    if(binary_strings == ON) {
 
454
            binary_strings(state) = TRUE;  
 
455
    } else {
 
456
            binary_strings(state) = FALSE;  
 
457
    }
 
458
    
449
459
    if(use_srollable_cursors == ON) {
450
 
        use_srollable_cursors(state) = TRUE;
 
460
            use_srollable_cursors(state) = TRUE;
451
461
    } else {
452
 
        use_srollable_cursors(state) = FALSE;
 
462
            use_srollable_cursors(state) = FALSE;
453
463
    }
454
 
  
 
464
 
455
465
    init_driver(erl_auto_commit_mode, erl_trace_driver, state); 
456
466
      
457
467
    connlen = (SQLSMALLINT)strlen((const char*)connStrIn);
462
472
                              &stringlength2ptr, SQL_DRIVER_NOPROMPT);
463
473
  
464
474
    if (!sql_success(result)) {
465
 
        diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state));
 
475
        diagnos = get_diagnos(SQL_HANDLE_DBC, connection_handle(state));
466
476
        strcat((char *)diagnos.error_msg,
467
477
               " Connection to database failed.");
468
478
        msg = encode_error_message(diagnos.error_msg);
749
759
    byte *sql; 
750
760
    db_result_msg msg; 
751
761
    int i, num_param_values, ver = 0,
752
 
        erl_type = 0, index = 0, size = 0, cols = 0; 
 
762
       erl_type = 0, index = 0, size = 0, cols = 0;
753
763
    long long_num_param_values;  
754
764
    param_status param_status;
755
765
    diagnos diagnos;
756
 
    param_array *params; 
 
766
    param_array *params;
 
767
    SQLRETURN result;
757
768
 
758
769
    if (associated_result_set(state)) {
759
770
        clean_state(state);
784
795
                                   num_param_values, state);  
785
796
    
786
797
    if(params != NULL) {
787
 
        if(!sql_success(SQLExecDirect(statement_handle(state),
788
 
                                      sql, SQL_NTS))) {
789
 
            diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state));
790
 
            msg = encode_error_message(diagnos.error_msg);
 
798
 
 
799
        result = SQLExecDirect(statement_handle(state), sql, SQL_NTS);
 
800
        if (!sql_success(result) || result == SQL_NO_DATA) {
 
801
                diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state));
 
802
        }
 
803
        /* SQL_NO_DATA and SQLSTATE 00000 indicate success for
 
804
           updates/deletes that affect no rows */
 
805
        if(!sql_success(result) &&
 
806
           !(result == SQL_NO_DATA && !strcmp((char *)diagnos.sqlState, INFO))) {
 
807
                msg = encode_error_message(diagnos.error_msg);
791
808
        } else {
792
809
            for (i = 0; i < param_status.params_processed; i++) {
793
810
                switch (param_status.param_status_array[i]) {
1064
1081
    int j = 0;
1065
1082
    param_array column;
1066
1083
    db_result_msg msg;
 
1084
    TIMESTAMP_STRUCT* ts;
1067
1085
    msg = encode_empty_message();
1068
1086
    
1069
1087
    ei_x_encode_tuple_header(&dynamic_buffer(state), 3);
1093
1111
            } else {
1094
1112
                void* values = retrive_param_values(&column);
1095
1113
                switch(column.type.c) {
 
1114
                case SQL_C_TYPE_TIMESTAMP:
 
1115
                  ts = (TIMESTAMP_STRUCT*) values;
 
1116
                  ei_x_encode_tuple_header(&dynamic_buffer(state), 2);
 
1117
                  ei_x_encode_tuple_header(&dynamic_buffer(state), 3);
 
1118
                  ei_x_encode_long(&dynamic_buffer(state), (long)(ts->year));
 
1119
                  ei_x_encode_long(&dynamic_buffer(state), (long)(ts->month));
 
1120
                  ei_x_encode_long(&dynamic_buffer(state), (long)(ts->day));
 
1121
                  ei_x_encode_tuple_header(&dynamic_buffer(state), 3);
 
1122
                  ei_x_encode_long(&dynamic_buffer(state), (long)(ts->hour));
 
1123
                  ei_x_encode_long(&dynamic_buffer(state), (long)(ts->minute));
 
1124
                  ei_x_encode_long(&dynamic_buffer(state), (long)(ts->second));
 
1125
                  break;
1096
1126
                case SQL_C_CHAR:
1097
 
                    ei_x_encode_string(&dynamic_buffer(state), ((char*)values)+j*column.type.len);
1098
 
                    break;
 
1127
                        if binary_strings(state) {
 
1128
                                ei_x_encode_binary(&dynamic_buffer(state),
 
1129
                                                   ((char*)values)+j*column.type.len,
 
1130
                                                   (column.type.strlen_or_indptr_array[j]));
 
1131
                        }
 
1132
                        else {
 
1133
                                ei_x_encode_string(&dynamic_buffer(state),
 
1134
                                                   ((char*)values)+j*column.type.len);
 
1135
                        }
 
1136
                        break;
 
1137
                case SQL_C_WCHAR:
 
1138
                        ei_x_encode_binary(&dynamic_buffer(state),
 
1139
                                           ((char*)values)+j*column.type.len,
 
1140
                                           (column.type.strlen_or_indptr_array[j]));
 
1141
                        break;
1099
1142
                case SQL_C_SLONG:
1100
1143
                    ei_x_encode_long(&dynamic_buffer(state), ((long*)values)[j]);
1101
1144
                    break;
1351
1394
static void encode_column_dyn(db_column column, int column_nr,
1352
1395
                              db_state *state)
1353
1396
{
 
1397
    TIMESTAMP_STRUCT* ts;
1354
1398
    if (column.type.len == 0 ||
1355
1399
        column.type.strlen_or_indptr == SQL_NULL_DATA) {
1356
1400
        ei_x_encode_atom(&dynamic_buffer(state), "null");
1357
1401
    } else {
1358
1402
        switch(column.type.c) {
 
1403
        case SQL_C_TYPE_TIMESTAMP:
 
1404
            ts = (TIMESTAMP_STRUCT*)column.buffer;
 
1405
            ei_x_encode_tuple_header(&dynamic_buffer(state), 2);
 
1406
            ei_x_encode_tuple_header(&dynamic_buffer(state), 3);
 
1407
            ei_x_encode_ulong(&dynamic_buffer(state), ts->year);
 
1408
            ei_x_encode_ulong(&dynamic_buffer(state), ts->month);
 
1409
            ei_x_encode_ulong(&dynamic_buffer(state), ts->day);
 
1410
            ei_x_encode_tuple_header(&dynamic_buffer(state), 3);
 
1411
            ei_x_encode_ulong(&dynamic_buffer(state), ts->hour);
 
1412
            ei_x_encode_ulong(&dynamic_buffer(state), ts->minute);
 
1413
            ei_x_encode_ulong(&dynamic_buffer(state), ts->second);
 
1414
            break;
1359
1415
        case SQL_C_CHAR:
1360
 
            ei_x_encode_string(&dynamic_buffer(state), column.buffer);
 
1416
                if binary_strings(state) {
 
1417
                         ei_x_encode_binary(&dynamic_buffer(state), 
 
1418
                                            column.buffer,column.type.strlen_or_indptr);
 
1419
                } else {
 
1420
                        ei_x_encode_string(&dynamic_buffer(state), column.buffer);
 
1421
                }
 
1422
            break;
 
1423
        case SQL_C_WCHAR:
 
1424
            ei_x_encode_binary(&dynamic_buffer(state), 
 
1425
                               column.buffer,column.type.strlen_or_indptr);
1361
1426
            break;
1362
1427
        case SQL_C_SLONG:
1363
1428
            ei_x_encode_long(&dynamic_buffer(state),
1371
1436
            ei_x_encode_atom(&dynamic_buffer(state),
1372
1437
                             column.buffer[0]?"true":"false");
1373
1438
            break;
1374
 
        case SQL_C_BINARY:
 
1439
        case SQL_C_BINARY:              
1375
1440
            column = retrive_binary_data(column, column_nr, state);
1376
 
            ei_x_encode_string(&dynamic_buffer(state), (void *)column.buffer);
 
1441
            if binary_strings(state) {
 
1442
                    ei_x_encode_binary(&dynamic_buffer(state), 
 
1443
                                       column.buffer,column.type.strlen_or_indptr);
 
1444
            } else {
 
1445
                    ei_x_encode_string(&dynamic_buffer(state), (void *)column.buffer);
 
1446
            }
1377
1447
            break;
1378
1448
        default:
1379
1449
            ei_x_encode_atom(&dynamic_buffer(state), "error");
1396
1466
        ei_x_encode_atom(&dynamic_buffer(state), "sql_varchar");
1397
1467
        ei_x_encode_long(&dynamic_buffer(state), size);
1398
1468
        break;
 
1469
    case SQL_WCHAR:
 
1470
        ei_x_encode_tuple_header(&dynamic_buffer(state), 2);    
 
1471
        ei_x_encode_atom(&dynamic_buffer(state), "sql_wchar");
 
1472
        ei_x_encode_long(&dynamic_buffer(state), size);
 
1473
        break;
 
1474
    case SQL_WVARCHAR:
 
1475
        ei_x_encode_tuple_header(&dynamic_buffer(state), 2);    
 
1476
        ei_x_encode_atom(&dynamic_buffer(state), "sql_wvarchar");
 
1477
        ei_x_encode_long(&dynamic_buffer(state), size);
 
1478
        break;
1399
1479
    case SQL_NUMERIC:
1400
1480
        ei_x_encode_tuple_header(&dynamic_buffer(state), 3);    
1401
1481
        ei_x_encode_atom(&dynamic_buffer(state), "sql_numeric");
1438
1518
        ei_x_encode_atom(&dynamic_buffer(state), "SQL_TYPE_TIME");
1439
1519
        break;
1440
1520
    case SQL_TYPE_TIMESTAMP:
1441
 
        ei_x_encode_atom(&dynamic_buffer(state), "SQL_TYPE_TIMESTAMP");
 
1521
        ei_x_encode_atom(&dynamic_buffer(state), "sql_timestamp");
1442
1522
        break;
1443
1523
    case SQL_BIGINT:
1444
1524
        ei_x_encode_atom(&dynamic_buffer(state), "SQL_BIGINT");
1484
1564
    }
1485
1565
}
1486
1566
 
1487
 
static Boolean decode_params(byte *buffer, int *index, param_array **params,
 
1567
static Boolean decode_params(db_state *state, byte *buffer, int *index, param_array **params,
1488
1568
                          int i, int j)
1489
1569
{
1490
1570
    int erl_type, size;
1491
1571
    long bin_size, l64;
 
1572
    long val;
1492
1573
    param_array* param;
1493
 
  
 
1574
    TIMESTAMP_STRUCT* ts;
 
1575
    
1494
1576
    ei_get_type(buffer, index, &erl_type, &size);
1495
1577
    param = &(*params)[i];
1496
1578
 
1497
1579
    switch (param->type.c) {
1498
1580
    case SQL_C_CHAR:
1499
 
        if(erl_type != ERL_STRING_EXT) {
1500
 
            return FALSE;
1501
 
        }
1502
 
 
1503
 
        ei_decode_string(buffer, index, &(param->values.string[param->offset]));
1504
 
        param->offset += param->type.len;
1505
 
        param->type.strlen_or_indptr_array[j] = SQL_NTS;
1506
 
        break;
1507
 
 
 
1581
            if (binary_strings(state)) {
 
1582
                    ei_decode_binary(buffer, index,
 
1583
                                     &(param->values.string[param->offset]), &bin_size);
 
1584
                    param->offset += param->type.len;
 
1585
                    param->type.strlen_or_indptr_array[j] = SQL_NTS;
 
1586
            } else {
 
1587
                    if(erl_type != ERL_STRING_EXT) {
 
1588
                            return FALSE;
 
1589
                    }
 
1590
                    ei_decode_string(buffer, index, &(param->values.string[param->offset]));
 
1591
                    param->offset += param->type.len;
 
1592
                    param->type.strlen_or_indptr_array[j] = SQL_NTS;
 
1593
            }
 
1594
            break;
 
1595
    case SQL_C_WCHAR:
 
1596
            ei_decode_binary(buffer, index, &(param->values.string[param->offset]), &bin_size);
 
1597
            param->offset += param->type.len;
 
1598
            param->type.strlen_or_indptr_array[j] = SQL_NTS;
 
1599
            break;
 
1600
    case SQL_C_TYPE_TIMESTAMP:
 
1601
            ts = (TIMESTAMP_STRUCT*) param->values.string;
 
1602
            ei_decode_tuple_header(buffer, index, &size);
 
1603
            ei_decode_long(buffer, index, &val);
 
1604
            ts[j].year = (SQLUSMALLINT)val;
 
1605
            ei_decode_long(buffer, index, &val);
 
1606
            ts[j].month = (SQLUSMALLINT)val;
 
1607
            ei_decode_long(buffer, index, &val);
 
1608
            ts[j].day = (SQLUSMALLINT)val;
 
1609
            ei_decode_long(buffer, index, &val);
 
1610
            ts[j].hour = (SQLUSMALLINT)val;
 
1611
            ei_decode_long(buffer, index, &val);
 
1612
            ts[j].minute = (SQLUSMALLINT)val;
 
1613
            ei_decode_long(buffer, index, &val);
 
1614
            ts[j].second = (SQLUSMALLINT)val;
 
1615
            ts[j].fraction = (SQLINTEGER)0;
 
1616
            break;
1508
1617
    case SQL_C_SLONG:
1509
 
        if(!((erl_type == ERL_SMALL_INTEGER_EXT) ||
1510
 
              (erl_type == ERL_INTEGER_EXT) ||
1511
 
              (erl_type == ERL_SMALL_BIG_EXT) ||
1512
 
              (erl_type == ERL_LARGE_BIG_EXT))) {
1513
 
            return FALSE;
1514
 
        }
1515
 
 
1516
 
        if(ei_decode_long(buffer, index, &l64)) {
1517
 
            return FALSE;
1518
 
        }
1519
 
 
1520
 
        /* For 64-bit platforms we downcast 8-byte long
1521
 
         * to 4-byte SQLINTEGER, checking for overflow */
1522
 
 
1523
 
        if(l64>INT_MAX || l64<INT_MIN) {
1524
 
            return FALSE;
1525
 
        }
 
1618
            if(!((erl_type == ERL_SMALL_INTEGER_EXT) ||
 
1619
                 (erl_type == ERL_INTEGER_EXT) ||
 
1620
                 (erl_type == ERL_SMALL_BIG_EXT) ||
 
1621
                 (erl_type == ERL_LARGE_BIG_EXT))) {
 
1622
                    return FALSE;
 
1623
            }
 
1624
            
 
1625
            if(ei_decode_long(buffer, index, &l64)) {
 
1626
                    return FALSE;
 
1627
            }
 
1628
            
 
1629
            /* For 64-bit platforms we downcast 8-byte long
 
1630
             * to 4-byte SQLINTEGER, checking for overflow */
 
1631
            
 
1632
            if(l64>INT_MAX || l64<INT_MIN) {
 
1633
                    return FALSE;
 
1634
            }
1526
1635
 
1527
1636
        param->values.integer[j]=(SQLINTEGER)l64;
1528
1637
        break;
1529
 
 
 
1638
        
1530
1639
    case SQL_C_DOUBLE: 
1531
 
        if((erl_type != ERL_FLOAT_EXT)) { 
1532
 
            return FALSE;
1533
 
        } 
1534
 
        ei_decode_double(buffer, index, &(param->values.floating[j])); 
1535
 
        break;
1536
 
 
 
1640
            if((erl_type != ERL_FLOAT_EXT)) { 
 
1641
                    return FALSE;
 
1642
            } 
 
1643
            ei_decode_double(buffer, index, &(param->values.floating[j])); 
 
1644
            break;
 
1645
            
1537
1646
    case SQL_C_BIT:
1538
1647
        if((erl_type != ERL_ATOM_EXT)) {
1539
 
            return FALSE;
 
1648
                return FALSE;
1540
1649
        }
1541
1650
        ei_decode_boolean(buffer, index, &(param->values.bool[j]));
1542
1651
        break;
1543
 
 
 
1652
        
1544
1653
    default:
1545
 
        return FALSE;
 
1654
            return FALSE;
1546
1655
    }
1547
 
 
 
1656
    
1548
1657
    return TRUE;
1549
1658
}  
1550
1659
 
1618
1727
}
1619
1728
 
1620
1729
/* ------------- Socket communication functions --------------------------*/
1621
 
#define USE_IPV4
1622
 
#ifdef UNIX
1623
 
#define SOCKET int   
1624
 
#endif
1625
1730
 
1626
 
#if defined WIN32 || defined USE_IPV4
1627
 
/* Currently only an old windows compiler is supported so we do not have ipv6
1628
 
  capabilities */
 
1731
#if defined(WIN32)
1629
1732
static SOCKET connect_to_erlang(const char *port)
1630
 
{
1631
 
    SOCKET sock;
1632
 
    struct sockaddr_in sin;
1633
 
    
1634
 
    sock = socket(AF_INET, SOCK_STREAM, 0);
1635
 
    
1636
 
    memset(&sin, 0, sizeof(sin));
1637
 
    sin.sin_port = htons ((unsigned short)atoi(port));
1638
 
    sin.sin_family = AF_INET;
1639
 
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
1640
 
    
1641
 
    if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
1642
 
        close_socket(sock);
1643
 
        DO_EXIT(EXIT_SOCKET_CONNECT);
1644
 
    }
1645
 
    return sock;
1646
 
}
1647
1733
#elif defined(UNIX)
1648
1734
static int connect_to_erlang(const char *port)
 
1735
#endif
1649
1736
{
1650
 
    int sock;
1651
 
    
1652
 
    struct addrinfo hints;
1653
 
    struct addrinfo *erlang_ai, *first;
1654
 
    
1655
 
    memset(&hints, 0, sizeof(hints));
1656
 
    hints.ai_family = PF_UNSPEC; /* PF_INET or PF_INET6 */
1657
 
    hints.ai_socktype = SOCK_STREAM;
1658
 
    hints.ai_protocol = IPPROTO_TCP;
1659
 
    
1660
 
    if (getaddrinfo("localhost", port, &hints, &first) != 0) {
1661
 
        DO_EXIT(EXIT_FAILURE);
1662
 
    }
1663
 
    
1664
 
    for (erlang_ai = first; erlang_ai; erlang_ai = erlang_ai->ai_next) {
 
1737
#if defined(WIN32)
 
1738
        SOCKET sock;
 
1739
#elif defined(UNIX)
 
1740
        int sock;
 
1741
#endif
 
1742
        struct sockaddr_in sin;
 
1743
 
 
1744
#if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_ADDR) && defined(AF_INET6)
 
1745
        struct sockaddr_in6 sin6;
 
1746
 
 
1747
        sock = socket(AF_INET6, SOCK_STREAM, 0);
 
1748
 
 
1749
        memset(&sin6, 0, sizeof(sin6));
 
1750
        sin6.sin6_port = htons ((unsigned short)atoi(port));
 
1751
        sin6.sin6_family = AF_INET6;
 
1752
        sin6.sin6_addr = in6addr_loopback;
 
1753
    
 
1754
        if (connect(sock, (struct sockaddr*)&sin6, sizeof(sin6)) == 0) {
 
1755
                return sock;
 
1756
        }
 
1757
        close_socket(sock);
 
1758
#endif
 
1759
        sock = socket(AF_INET, SOCK_STREAM, 0);
 
1760
 
 
1761
        memset(&sin, 0, sizeof(sin));
 
1762
        sin.sin_port = htons ((unsigned short)atoi(port));
 
1763
        sin.sin_family = AF_INET;
 
1764
        sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1665
1765
        
1666
 
        sock = socket(erlang_ai->ai_family, erlang_ai->ai_socktype,
1667
 
                      erlang_ai->ai_protocol);
1668
 
        if (sock < 0)
1669
 
            continue;
1670
 
        if (connect(sock,  (struct sockaddr*)erlang_ai->ai_addr,
1671
 
                    erlang_ai->ai_addrlen) < 0) {
1672
 
            close(sock); 
1673
 
            sock = -1;
1674
 
            continue;
1675
 
        } else {
1676
 
            break;
 
1766
        if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
 
1767
                close_socket(sock);
 
1768
                DO_EXIT(EXIT_SOCKET_CONNECT);
1677
1769
        }
1678
 
    }
1679
 
    freeaddrinfo(first); 
1680
 
    
1681
 
    if (sock < 0){
1682
 
        close_socket(sock); 
1683
 
        DO_EXIT(EXIT_SOCKET_CONNECT); 
1684
 
    }
1685
 
    
1686
 
    return sock;
 
1770
        return sock;
1687
1771
}
1688
 
#endif
1689
1772
 
1690
1773
#ifdef WIN32
1691
1774
static void close_socket(SOCKET socket)
1924
2007
                        db_state *state)
1925
2008
{
1926
2009
  
1927
 
    int auto_commit_mode, trace_driver, use_srollable_cursors;
 
2010
    int auto_commit_mode, trace_driver;
1928
2011
  
1929
2012
    if(erl_auto_commit_mode == ON) {
1930
2013
        auto_commit_mode = SQL_AUTOCOMMIT_ON;
1950
2033
                                   environment_handle(state),
1951
2034
                                   &connection_handle(state))))
1952
2035
        DO_EXIT(EXIT_ALLOC);
 
2036
    /* By default Erlang handles all timeouts */
1953
2037
    if(!sql_success(SQLSetConnectAttr(connection_handle(state),
1954
2038
                                      SQL_ATTR_CONNECTION_TIMEOUT,
1955
2039
                                      (SQLPOINTER)TIME_OUT, 0)))
1956
 
        DO_EXIT(EXIT_CONNECTION);
 
2040
            DO_EXIT(EXIT_CONNECTION);
1957
2041
    if(!sql_success(SQLSetConnectAttr(connection_handle(state),
1958
2042
                                      SQL_ATTR_AUTOCOMMIT,
1959
2043
                                      (SQLPOINTER)auto_commit_mode, 0)))
1960
 
        DO_EXIT(EXIT_CONNECTION);
 
2044
            DO_EXIT(EXIT_CONNECTION);
1961
2045
    if(!sql_success(SQLSetConnectAttr(connection_handle(state),
1962
2046
                                      SQL_ATTR_TRACE,
1963
2047
                                      (SQLPOINTER)trace_driver, 0)))
1964
 
        DO_EXIT(EXIT_CONNECTION);
 
2048
            DO_EXIT(EXIT_CONNECTION);
1965
2049
}
1966
2050
 
1967
2051
static void init_param_column(param_array *params, byte *buffer, int *index,
2045
2129
                                sizeof(byte)* params->type.len);
2046
2130
        
2047
2131
        break;
 
2132
    case USER_WCHAR:
 
2133
    case USER_WVARCHAR:
 
2134
        if(user_type == USER_WCHAR) {
 
2135
            params->type.sql = SQL_WCHAR;
 
2136
        } else {
 
2137
            params->type.sql = SQL_WVARCHAR;
 
2138
        }
 
2139
        ei_decode_long(buffer, index, &length);
 
2140
        /* Max string length + string terminator */
 
2141
        params->type.len = (length+1)*sizeof(SQLWCHAR);
 
2142
        params->type.c = SQL_C_WCHAR;
 
2143
        params->type.col_size = (SQLUINTEGER)length;
 
2144
        params->type.strlen_or_indptr_array =
 
2145
          (SQLLEN*)safe_malloc(num_param_values * sizeof(SQLINTEGER));
 
2146
        params->values.string =
 
2147
          (byte *)safe_malloc(num_param_values * sizeof(byte) * params->type.len);
 
2148
        
 
2149
        break;
 
2150
    case USER_TIMESTAMP:
 
2151
      params->type.sql = SQL_TYPE_TIMESTAMP;
 
2152
      params->type.len = sizeof(TIMESTAMP_STRUCT);
 
2153
      params->type.c = SQL_C_TYPE_TIMESTAMP;
 
2154
      params->type.col_size = (SQLUINTEGER)COL_SQL_TIMESTAMP;
 
2155
      params->values.string =
 
2156
        (byte *)safe_malloc(num_param_values * params->type.len);
 
2157
      break;
2048
2158
    case USER_FLOAT:
2049
2159
        params->type.sql = SQL_FLOAT;
2050
2160
        params->type.c = SQL_C_DOUBLE;
2182
2292
    case SQL_LONGVARCHAR:
2183
2293
    case SQL_VARBINARY:
2184
2294
    case SQL_LONGVARBINARY:
2185
 
        column -> type.len = (column -> type.col_size) +
2186
 
            /* Make place for NULL termination */
2187
 
            sizeof(byte);
2188
 
        column -> type.c = SQL_C_CHAR;
2189
 
        column -> type.strlen_or_indptr = SQL_NTS;
 
2295
        column -> type.len = (column -> type.col_size) +
 
2296
            /* Make place for NULL termination */
 
2297
            sizeof(byte);
 
2298
        column -> type.c = SQL_C_CHAR;
 
2299
        column -> type.strlen_or_indptr = SQL_NTS;
 
2300
        break;
 
2301
    case SQL_WCHAR:
 
2302
    case SQL_WVARCHAR:
 
2303
        column -> type.len = (column -> type.col_size + 1)*sizeof(SQLWCHAR); 
 
2304
        column -> type.c = SQL_C_WCHAR;
 
2305
        column -> type.strlen_or_indptr = SQL_NTS;
2190
2306
        break;
2191
2307
    case SQL_NUMERIC:
2192
2308
    case SQL_DECIMAL:
2210
2326
        break;
2211
2327
    case SQL_TYPE_DATE:
2212
2328
    case SQL_TYPE_TIME:
2213
 
    case SQL_TYPE_TIMESTAMP:
2214
2329
        column -> type.len = (column -> type.col_size) +
2215
2330
            sizeof(byte);
2216
2331
        column -> type.c = SQL_C_CHAR;
2217
2332
        column -> type.strlen_or_indptr = SQL_NTS;
2218
2333
        break;
 
2334
    case SQL_TYPE_TIMESTAMP:
 
2335
      column -> type.len = sizeof(TIMESTAMP_STRUCT);
 
2336
      column -> type.c = SQL_C_TYPE_TIMESTAMP;
 
2337
      column -> type.strlen_or_indptr = (SQLINTEGER)NULL;
 
2338
      break;
2219
2339
    case SQL_BIGINT:
2220
2340
        column -> type.len = DEC_NUM_LENGTH;
2221
2341
        column -> type.c = SQL_C_CHAR;
2272
2392
        }
2273
2393
  
2274
2394
        for (j = 0; j < num_param_values; j++) {
2275
 
            if(!decode_params(buffer, index, &params, i, j)) {
 
2395
            if(!decode_params(state, buffer, index, &params, i, j)) {
2276
2396
                /* An input parameter was not of the expected type */  
2277
2397
                free_params(&params, i);
2278
2398
                return params;
2301
2421
{
2302
2422
    switch(Param->type.c) {
2303
2423
    case SQL_C_CHAR:
2304
 
        return (void *)Param->values.string;
 
2424
    case SQL_C_WCHAR:
 
2425
    case SQL_C_TYPE_TIMESTAMP:
 
2426
        return (void *)Param->values.string;
2305
2427
    case SQL_C_SLONG:
2306
2428
        return (void *)Param->values.integer;
2307
2429
    case SQL_C_DOUBLE: 
2452
2574
    int acc_errmsg_size;
2453
2575
    byte *current_errmsg_pos;
2454
2576
    SQLCHAR current_sql_state[SQL_STATE_SIZE];
 
2577
    SQLRETURN result;
2455
2578
 
2456
2579
    diagnos.error_msg[0] = 0;
2457
2580
    
2464
2587
    /* Foreach diagnostic record in the current set of diagnostic records
2465
2588
       the error message is obtained */
2466
2589
    for(record_nr = 1; ;record_nr++) {    
2467
 
        if(SQLGetDiagRec(handleType, handle, record_nr, current_sql_state,
 
2590
        result = SQLGetDiagRec(handleType, handle, record_nr, current_sql_state,
2468
2591
                         &nativeError, current_errmsg_pos,
2469
 
                         (SQLSMALLINT)errmsg_buffer_size, &errmsg_size)
2470
 
           != SQL_SUCCESS) {
 
2592
                                                           (SQLSMALLINT)errmsg_buffer_size, &errmsg_size);
 
2593
        if(result != SQL_SUCCESS && result != SQL_NO_DATA) {
2471
2594
 
2472
2595
      
2473
2596
            break;