diff options
Diffstat (limited to 'src/interfaces/odbc/connection.c')
-rw-r--r-- | src/interfaces/odbc/connection.c | 1359 |
1 files changed, 742 insertions, 617 deletions
diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c index a4f0526184f..bdb23a8d089 100644 --- a/src/interfaces/odbc/connection.c +++ b/src/interfaces/odbc/connection.c @@ -1,15 +1,15 @@ -/* Module: connection.c +/* Module: connection.c * - * Description: This module contains routines related to - * connecting to and disconnecting from the Postgres DBMS. + * Description: This module contains routines related to + * connecting to and disconnecting from the Postgres DBMS. * - * Classes: ConnectionClass (Functions prefix: "CC_") + * Classes: ConnectionClass (Functions prefix: "CC_") * - * API functions: SQLAllocConnect, SQLConnect, SQLDisconnect, SQLFreeConnect, - * SQLBrowseConnect(NI) + * API functions: SQLAllocConnect, SQLConnect, SQLDisconnect, SQLFreeConnect, + * SQLBrowseConnect(NI) * - * Comments: See "notice.txt" for copyright and license information. + * Comments: See "notice.txt" for copyright and license information. * */ /* Multibyte support Eiji Tokuya 2001-03-15 */ @@ -37,67 +37,73 @@ #include <odbcinst.h> #endif -#define STMT_INCREMENT 16 /* how many statement holders to allocate at a time */ +#define STMT_INCREMENT 16 /* how many statement holders to allocate + * at a time */ #define PRN_NULLCHECK extern GLOBAL_VALUES globals; -RETCODE SQL_API SQLAllocConnect( - HENV henv, - HDBC FAR *phdbc) +RETCODE SQL_API +SQLAllocConnect( + HENV henv, + HDBC FAR *phdbc) { -EnvironmentClass *env = (EnvironmentClass *)henv; -ConnectionClass *conn; -static char *func="SQLAllocConnect"; + EnvironmentClass *env = (EnvironmentClass *) henv; + ConnectionClass *conn; + static char *func = "SQLAllocConnect"; - mylog( "%s: entering...\n", func); + mylog("%s: entering...\n", func); conn = CC_Constructor(); mylog("**** %s: henv = %u, conn = %u\n", func, henv, conn); - if( ! conn) { - env->errormsg = "Couldn't allocate memory for Connection object."; - env->errornumber = ENV_ALLOC_ERROR; + if (!conn) + { + env->errormsg = "Couldn't allocate memory for Connection object."; + env->errornumber = ENV_ALLOC_ERROR; *phdbc = SQL_NULL_HDBC; EN_log_error(func, "", env); - return SQL_ERROR; - } + return SQL_ERROR; + } - if ( ! EN_add_connection(env, conn)) { - env->errormsg = "Maximum number of connections exceeded."; - env->errornumber = ENV_ALLOC_ERROR; - CC_Destructor(conn); + if (!EN_add_connection(env, conn)) + { + env->errormsg = "Maximum number of connections exceeded."; + env->errornumber = ENV_ALLOC_ERROR; + CC_Destructor(conn); *phdbc = SQL_NULL_HDBC; EN_log_error(func, "", env); - return SQL_ERROR; - } + return SQL_ERROR; + } *phdbc = (HDBC) conn; - return SQL_SUCCESS; + return SQL_SUCCESS; } -/* - - - - - - - - - */ +/* - - - - - - - - - */ -RETCODE SQL_API SQLConnect( - HDBC hdbc, - UCHAR FAR *szDSN, - SWORD cbDSN, - UCHAR FAR *szUID, - SWORD cbUID, - UCHAR FAR *szAuthStr, - SWORD cbAuthStr) +RETCODE SQL_API +SQLConnect( + HDBC hdbc, + UCHAR FAR *szDSN, + SWORD cbDSN, + UCHAR FAR *szUID, + SWORD cbUID, + UCHAR FAR *szAuthStr, + SWORD cbAuthStr) { -ConnectionClass *conn = (ConnectionClass *) hdbc; -ConnInfo *ci; -static char *func = "SQLConnect"; + ConnectionClass *conn = (ConnectionClass *) hdbc; + ConnInfo *ci; + static char *func = "SQLConnect"; - mylog( "%s: entering...\n", func); + mylog("%s: entering...\n", func); - if ( ! conn) { + if (!conn) + { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } @@ -106,14 +112,15 @@ static char *func = "SQLConnect"; make_string(szDSN, cbDSN, ci->dsn); - /* get the values for the DSN from the registry */ + /* get the values for the DSN from the registry */ getDSNinfo(ci, CONN_OVERWRITE); - /* initialize pg_version from connInfo.protocol */ - CC_initialize_pg_version(conn); - - /* override values from DSN info with UID and authStr(pwd) - This only occurs if the values are actually there. - */ + /* initialize pg_version from connInfo.protocol */ + CC_initialize_pg_version(conn); + + /* + * override values from DSN info with UID and authStr(pwd) This only + * occurs if the values are actually there. + */ make_string(szUID, cbUID, ci->username); make_string(szAuthStr, cbAuthStr, ci->password); @@ -122,54 +129,59 @@ static char *func = "SQLConnect"; qlog("conn = %u, %s(DSN='%s', UID='%s', PWD='%s')\n", conn, func, ci->dsn, ci->username, ci->password); - if ( CC_connect(conn, FALSE) <= 0) { - /* Error messages are filled in */ + if (CC_connect(conn, FALSE) <= 0) + { + /* Error messages are filled in */ CC_log_error(func, "Error on CC_connect", conn); return SQL_ERROR; } - mylog( "%s: returning...\n", func); + mylog("%s: returning...\n", func); return SQL_SUCCESS; } -/* - - - - - - - - - */ +/* - - - - - - - - - */ -RETCODE SQL_API SQLBrowseConnect( - HDBC hdbc, - UCHAR FAR *szConnStrIn, - SWORD cbConnStrIn, - UCHAR FAR *szConnStrOut, - SWORD cbConnStrOutMax, - SWORD FAR *pcbConnStrOut) +RETCODE SQL_API +SQLBrowseConnect( + HDBC hdbc, + UCHAR FAR *szConnStrIn, + SWORD cbConnStrIn, + UCHAR FAR *szConnStrOut, + SWORD cbConnStrOutMax, + SWORD FAR *pcbConnStrOut) { -static char *func="SQLBrowseConnect"; + static char *func = "SQLBrowseConnect"; - mylog( "%s: entering...\n", func); + mylog("%s: entering...\n", func); return SQL_SUCCESS; } -/* - - - - - - - - - */ +/* - - - - - - - - - */ /* Drop any hstmts open on hdbc and disconnect from database */ -RETCODE SQL_API SQLDisconnect( - HDBC hdbc) +RETCODE SQL_API +SQLDisconnect( + HDBC hdbc) { -ConnectionClass *conn = (ConnectionClass *) hdbc; -static char *func = "SQLDisconnect"; + ConnectionClass *conn = (ConnectionClass *) hdbc; + static char *func = "SQLDisconnect"; - mylog( "%s: entering...\n", func); + mylog("%s: entering...\n", func); - if ( ! conn) { + if (!conn) + { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } qlog("conn=%u, %s\n", conn, func); - if (conn->status == CONN_EXECUTING) { + if (conn->status == CONN_EXECUTING) + { conn->errornumber = CONN_IN_USE; conn->errormsg = "A transaction is currently being executed"; CC_log_error(func, "", conn); @@ -178,7 +190,7 @@ static char *func = "SQLDisconnect"; mylog("%s: about to CC_cleanup\n", func); - /* Close the connection and free statements */ + /* Close the connection and free statements */ CC_cleanup(conn); mylog("%s: done CC_cleanup\n", func); @@ -188,24 +200,27 @@ static char *func = "SQLDisconnect"; } -/* - - - - - - - - - */ +/* - - - - - - - - - */ -RETCODE SQL_API SQLFreeConnect( - HDBC hdbc) +RETCODE SQL_API +SQLFreeConnect( + HDBC hdbc) { -ConnectionClass *conn = (ConnectionClass *) hdbc; -static char *func = "SQLFreeConnect"; + ConnectionClass *conn = (ConnectionClass *) hdbc; + static char *func = "SQLFreeConnect"; - mylog( "%s: entering...\n", func); + mylog("%s: entering...\n", func); mylog("**** in %s: hdbc=%u\n", func, hdbc); - if ( ! conn) { + if (!conn) + { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } - /* Remove the connection from the environment */ - if ( ! EN_remove_connection(conn->henv, conn)) { + /* Remove the connection from the environment */ + if (!EN_remove_connection(conn->henv, conn)) + { conn->errornumber = CONN_IN_USE; conn->errormsg = "A transaction is currently being executed"; CC_log_error(func, "", conn); @@ -222,35 +237,37 @@ static char *func = "SQLFreeConnect"; /* * -* IMPLEMENTATION CONNECTION CLASS +* IMPLEMENTATION CONNECTION CLASS * */ -ConnectionClass *CC_Constructor() +ConnectionClass * +CC_Constructor() { -ConnectionClass *rv; + ConnectionClass *rv; - rv = (ConnectionClass *)malloc(sizeof(ConnectionClass)); + rv = (ConnectionClass *) malloc(sizeof(ConnectionClass)); - if (rv != NULL) { + if (rv != NULL) + { - rv->henv = NULL; /* not yet associated with an environment */ + rv->henv = NULL; /* not yet associated with an environment */ - rv->errormsg = NULL; - rv->errornumber = 0; + rv->errormsg = NULL; + rv->errornumber = 0; rv->errormsg_created = FALSE; - rv->status = CONN_NOT_CONNECTED; - rv->transact_status = CONN_IN_AUTOCOMMIT; /* autocommit by default */ + rv->status = CONN_NOT_CONNECTED; + rv->transact_status = CONN_IN_AUTOCOMMIT; /* autocommit by default */ memset(&rv->connInfo, 0, sizeof(ConnInfo)); rv->sock = SOCK_Constructor(); - if ( ! rv->sock) + if (!rv->sock) return NULL; - rv->stmts = (StatementClass **) malloc( sizeof(StatementClass *) * STMT_INCREMENT); - if ( ! rv->stmts) + rv->stmts = (StatementClass **) malloc(sizeof(StatementClass *) * STMT_INCREMENT); + if (!rv->stmts) return NULL; memset(rv->stmts, 0, sizeof(StatementClass *) * STMT_INCREMENT); @@ -271,14 +288,14 @@ ConnectionClass *rv; rv->pg_version_minor = 0; - /* Initialize statement options to defaults */ - /* Statements under this conn will inherit these options */ + /* Initialize statement options to defaults */ + /* Statements under this conn will inherit these options */ InitializeStatementOptions(&rv->stmtOptions); - } - return rv; + } + return rv; } @@ -291,22 +308,27 @@ CC_Destructor(ConnectionClass *self) if (self->status == CONN_EXECUTING) return 0; - CC_cleanup(self); /* cleanup socket and statements */ + CC_cleanup(self); /* cleanup socket and statements */ mylog("after CC_Cleanup\n"); - /* Free up statement holders */ - if (self->stmts) { + /* Free up statement holders */ + if (self->stmts) + { free(self->stmts); self->stmts = NULL; } mylog("after free statement holders\n"); - /* Free cached table info */ - if (self->col_info) { - int i; - for (i = 0; i < self->ntables; i++) { - if (self->col_info[i]->result) /* Free the SQLColumns result structure */ + /* Free cached table info */ + if (self->col_info) + { + int i; + + for (i = 0; i < self->ntables; i++) + { + if (self->col_info[i]->result) /* Free the SQLColumns + * result structure */ QR_Destructor(self->col_info[i]->result); free(self->col_info[i]); @@ -326,12 +348,14 @@ CC_Destructor(ConnectionClass *self) int CC_cursor_count(ConnectionClass *self) { -StatementClass *stmt; -int i, count = 0; + StatementClass *stmt; + int i, + count = 0; mylog("CC_cursor_count: self=%u, num_stmts=%d\n", self, self->num_stmts); - for (i = 0; i < self->num_stmts; i++) { + for (i = 0; i < self->num_stmts; i++) + { stmt = self->stmts[i]; if (stmt && stmt->result && stmt->result->cursor) count++; @@ -342,11 +366,11 @@ int i, count = 0; return count; } -void +void CC_clear_error(ConnectionClass *self) { - self->errornumber = 0; - self->errormsg = NULL; + self->errornumber = 0; + self->errormsg = NULL; self->errormsg_created = FALSE; } @@ -355,9 +379,10 @@ CC_clear_error(ConnectionClass *self) char CC_abort(ConnectionClass *self) { -QResultClass *res; + QResultClass *res; - if ( CC_is_in_trans(self)) { + if (CC_is_in_trans(self)) + { res = NULL; mylog("CC_abort: sending ABORT!\n"); @@ -379,8 +404,8 @@ QResultClass *res; char CC_cleanup(ConnectionClass *self) { -int i; -StatementClass *stmt; + int i; + StatementClass *stmt; if (self->status == CONN_EXECUTING) return FALSE; @@ -395,18 +420,21 @@ StatementClass *stmt; mylog("after CC_abort\n"); - /* This actually closes the connection to the dbase */ - if (self->sock) { - SOCK_Destructor(self->sock); + /* This actually closes the connection to the dbase */ + if (self->sock) + { + SOCK_Destructor(self->sock); self->sock = NULL; } mylog("after SOCK destructor\n"); - /* Free all the stmts on this connection */ - for (i = 0; i < self->num_stmts; i++) { + /* Free all the stmts on this connection */ + for (i = 0; i < self->num_stmts; i++) + { stmt = self->stmts[i]; - if (stmt) { + if (stmt) + { stmt->hdbc = NULL; /* prevent any more dbase interactions */ @@ -416,10 +444,11 @@ StatementClass *stmt; } } - /* Check for translation dll */ + /* Check for translation dll */ #ifdef WIN32 - if ( self->translation_handle) { - FreeLibrary (self->translation_handle); + if (self->translation_handle) + { + FreeLibrary(self->translation_handle); self->translation_handle = NULL; } #endif @@ -429,37 +458,40 @@ StatementClass *stmt; } int -CC_set_translation (ConnectionClass *self) +CC_set_translation(ConnectionClass *self) { #ifdef WIN32 - if (self->translation_handle != NULL) { - FreeLibrary (self->translation_handle); + if (self->translation_handle != NULL) + { + FreeLibrary(self->translation_handle); self->translation_handle = NULL; } if (self->connInfo.translation_dll[0] == 0) return TRUE; - self->translation_option = atoi (self->connInfo.translation_option); - self->translation_handle = LoadLibrary (self->connInfo.translation_dll); + self->translation_option = atoi(self->connInfo.translation_option); + self->translation_handle = LoadLibrary(self->connInfo.translation_dll); - if (self->translation_handle == NULL) { + if (self->translation_handle == NULL) + { self->errornumber = CONN_UNABLE_TO_LOAD_DLL; self->errormsg = "Could not load the translation DLL."; return FALSE; } self->DataSourceToDriver - = (DataSourceToDriverProc) GetProcAddress (self->translation_handle, + = (DataSourceToDriverProc) GetProcAddress(self->translation_handle, "SQLDataSourceToDriver"); self->DriverToDataSource - = (DriverToDataSourceProc) GetProcAddress (self->translation_handle, + = (DriverToDataSourceProc) GetProcAddress(self->translation_handle, "SQLDriverToDataSource"); - if (self->DataSourceToDriver == NULL || self->DriverToDataSource == NULL) { + if (self->DataSourceToDriver == NULL || self->DriverToDataSource == NULL) + { self->errornumber = CONN_UNABLE_TO_LOAD_DLL; self->errormsg = "Could not find translation DLL functions."; return FALSE; @@ -468,64 +500,67 @@ CC_set_translation (ConnectionClass *self) return TRUE; } -char +char CC_connect(ConnectionClass *self, char do_password) { -StartupPacket sp; -StartupPacket6_2 sp62; -QResultClass *res; -SocketClass *sock; -ConnInfo *ci = &(self->connInfo); -int areq = -1; -int beresp; -char msgbuffer[ERROR_MSG_LENGTH]; -char salt[2]; -static char *func="CC_connect"; + StartupPacket sp; + StartupPacket6_2 sp62; + QResultClass *res; + SocketClass *sock; + ConnInfo *ci = &(self->connInfo); + int areq = -1; + int beresp; + char msgbuffer[ERROR_MSG_LENGTH]; + char salt[2]; + static char *func = "CC_connect"; mylog("%s: entering...\n", func); - if ( do_password) + if (do_password) sock = self->sock; /* already connected, just authenticate */ - else { + else + { qlog("Global Options: Version='%s', fetch=%d, socket=%d, unknown_sizes=%d, max_varchar_size=%d, max_longvarchar_size=%d\n", - POSTGRESDRIVERVERSION, - globals.fetch_max, - globals.socket_buffersize, - globals.unknown_sizes, - globals.max_varchar_size, - globals.max_longvarchar_size); + POSTGRESDRIVERVERSION, + globals.fetch_max, + globals.socket_buffersize, + globals.unknown_sizes, + globals.max_varchar_size, + globals.max_longvarchar_size); qlog(" disable_optimizer=%d, ksqo=%d, unique_index=%d, use_declarefetch=%d\n", - globals.disable_optimizer, - globals.ksqo, - globals.unique_index, - globals.use_declarefetch); + globals.disable_optimizer, + globals.ksqo, + globals.unique_index, + globals.use_declarefetch); qlog(" text_as_longvarchar=%d, unknowns_as_longvarchar=%d, bools_as_char=%d\n", - globals.text_as_longvarchar, - globals.unknowns_as_longvarchar, - globals.bools_as_char); + globals.text_as_longvarchar, + globals.unknowns_as_longvarchar, + globals.bools_as_char); #ifdef MULTIBYTE check_client_encoding(globals.conn_settings); qlog(" extra_systable_prefixes='%s', conn_settings='%s' conn_encoding='%s'\n", - globals.extra_systable_prefixes, - globals.conn_settings, - check_client_encoding(globals.conn_settings)); + globals.extra_systable_prefixes, + globals.conn_settings, + check_client_encoding(globals.conn_settings)); #else qlog(" extra_systable_prefixes='%s', conn_settings='%s'\n", - globals.extra_systable_prefixes, - globals.conn_settings); + globals.extra_systable_prefixes, + globals.conn_settings); #endif - if (self->status != CONN_NOT_CONNECTED) { + if (self->status != CONN_NOT_CONNECTED) + { self->errormsg = "Already connected."; self->errornumber = CONN_OPENDB_ERROR; return 0; } - if ( ci->server[0] == '\0' || ci->port[0] == '\0' || ci->database[0] == '\0') { + if (ci->server[0] == '\0' || ci->port[0] == '\0' || ci->database[0] == '\0') + { self->errornumber = CONN_INIREAD_ERROR; self->errormsg = "Missing server name, port, or database name in call to CC_connect."; return 0; @@ -533,15 +568,18 @@ static char *func="CC_connect"; mylog("CC_connect(): DSN = '%s', server = '%s', port = '%s', database = '%s', username = '%s', password='%s'\n", ci->dsn, ci->server, ci->port, ci->database, ci->username, ci->password); - /* If the socket was closed for some reason (like a SQLDisconnect, but no SQLFreeConnect - then create a socket now. - */ - if ( ! self->sock) { + /* + * If the socket was closed for some reason (like a SQLDisconnect, + * but no SQLFreeConnect then create a socket now. + */ + if (!self->sock) + { self->sock = SOCK_Constructor(); - if ( ! self->sock) { - self->errornumber = CONNECTION_SERVER_NOT_REACHED; - self->errormsg = "Could not open a socket to the server"; - return 0; + if (!self->sock) + { + self->errornumber = CONNECTION_SERVER_NOT_REACHED; + self->errormsg = "Could not open a socket to the server"; + return 0; } } @@ -550,7 +588,8 @@ static char *func="CC_connect"; mylog("connecting to the server socket...\n"); SOCK_connect_to(sock, (short) atoi(ci->port), ci->server); - if (SOCK_get_errcode(sock) != 0) { + if (SOCK_get_errcode(sock) != 0) + { mylog("connection to the server socket failed.\n"); self->errornumber = CONNECTION_SERVER_NOT_REACHED; self->errormsg = "Could not connect to the server"; @@ -558,26 +597,29 @@ static char *func="CC_connect"; } mylog("connection to the server socket succeeded.\n"); - if ( PROTOCOL_62(ci)) { - sock->reverse = TRUE; /* make put_int and get_int work for 6.2 */ + if (PROTOCOL_62(ci)) + { + sock->reverse = TRUE; /* make put_int and get_int work + * for 6.2 */ memset(&sp62, 0, sizeof(StartupPacket6_2)); - SOCK_put_int(sock, htonl(4+sizeof(StartupPacket6_2)), 4); + SOCK_put_int(sock, htonl(4 + sizeof(StartupPacket6_2)), 4); sp62.authtype = htonl(NO_AUTHENTICATION); strncpy(sp62.database, ci->database, PATH_SIZE); strncpy(sp62.user, ci->username, NAMEDATALEN); SOCK_put_n_char(sock, (char *) &sp62, sizeof(StartupPacket6_2)); SOCK_flush_output(sock); } - else { + else + { memset(&sp, 0, sizeof(StartupPacket)); mylog("sizeof startup packet = %d\n", sizeof(StartupPacket)); /* Send length of Authentication Block */ - SOCK_put_int(sock, 4+sizeof(StartupPacket), 4); + SOCK_put_int(sock, 4 + sizeof(StartupPacket), 4); - if ( PROTOCOL_63(ci)) + if (PROTOCOL_63(ci)) sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_63); else sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LATEST); @@ -591,7 +633,8 @@ static char *func="CC_connect"; mylog("sent the authentication block.\n"); - if (sock->errornumber != 0) { + if (sock->errornumber != 0) + { mylog("couldn't send the authentication block properly.\n"); self->errornumber = CONN_INVALID_AUTHENTICATION; self->errormsg = "Sending the authentication packet failed"; @@ -605,101 +648,109 @@ static char *func="CC_connect"; /* *************************************************** */ - /* Now get the authentication request from backend */ + /* Now get the authentication request from backend */ /* *************************************************** */ - if ( ! PROTOCOL_62(ci)) do { - - if (do_password) - beresp = 'R'; - else - beresp = SOCK_get_char(sock); - - switch(beresp) { - case 'E': - mylog("auth got 'E'\n"); - - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - self->errornumber = CONN_INVALID_AUTHENTICATION; - self->errormsg = msgbuffer; - qlog("ERROR from backend during authentication: '%s'\n", self->errormsg); - return 0; - case 'R': - - if (do_password) { - mylog("in 'R' do_password\n"); - areq = AUTH_REQ_PASSWORD; - do_password = FALSE; - } - else { - mylog("auth got 'R'\n"); - - areq = SOCK_get_int(sock, 4); - if (areq == AUTH_REQ_CRYPT) - SOCK_get_n_char(sock, salt, 2); + if (!PROTOCOL_62(ci)) + do + { - mylog("areq = %d\n", areq); - } - switch(areq) { - case AUTH_REQ_OK: - break; - - case AUTH_REQ_KRB4: - self->errormsg = "Kerberos 4 authentication not supported"; - self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; - return 0; - - case AUTH_REQ_KRB5: - self->errormsg = "Kerberos 5 authentication not supported"; - self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; - return 0; - - case AUTH_REQ_PASSWORD: - mylog("in AUTH_REQ_PASSWORD\n"); - - if (ci->password[0] == '\0') { - self->errornumber = CONNECTION_NEED_PASSWORD; - self->errormsg = "A password is required for this connection."; - return -1; /* need password */ - } - - mylog("past need password\n"); - - SOCK_put_int(sock, 4+strlen(ci->password)+1, 4); - SOCK_put_n_char(sock, ci->password, strlen(ci->password) + 1); - SOCK_flush_output(sock); - - mylog("past flush\n"); - break; + if (do_password) + beresp = 'R'; + else + beresp = SOCK_get_char(sock); + + switch (beresp) + { + case 'E': + mylog("auth got 'E'\n"); + + SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); + self->errornumber = CONN_INVALID_AUTHENTICATION; + self->errormsg = msgbuffer; + qlog("ERROR from backend during authentication: '%s'\n", self->errormsg); + return 0; + case 'R': + + if (do_password) + { + mylog("in 'R' do_password\n"); + areq = AUTH_REQ_PASSWORD; + do_password = FALSE; + } + else + { + mylog("auth got 'R'\n"); - case AUTH_REQ_CRYPT: - self->errormsg = "Password crypt authentication not supported"; - self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; - return 0; + areq = SOCK_get_int(sock, 4); + if (areq == AUTH_REQ_CRYPT) + SOCK_get_n_char(sock, salt, 2); - default: - self->errormsg = "Unknown authentication type"; - self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; - return 0; + mylog("areq = %d\n", areq); + } + switch (areq) + { + case AUTH_REQ_OK: + break; + + case AUTH_REQ_KRB4: + self->errormsg = "Kerberos 4 authentication not supported"; + self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; + return 0; + + case AUTH_REQ_KRB5: + self->errormsg = "Kerberos 5 authentication not supported"; + self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; + return 0; + + case AUTH_REQ_PASSWORD: + mylog("in AUTH_REQ_PASSWORD\n"); + + if (ci->password[0] == '\0') + { + self->errornumber = CONNECTION_NEED_PASSWORD; + self->errormsg = "A password is required for this connection."; + return -1; /* need password */ + } + + mylog("past need password\n"); + + SOCK_put_int(sock, 4 + strlen(ci->password) + 1, 4); + SOCK_put_n_char(sock, ci->password, strlen(ci->password) + 1); + SOCK_flush_output(sock); + + mylog("past flush\n"); + break; + + case AUTH_REQ_CRYPT: + self->errormsg = "Password crypt authentication not supported"; + self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; + return 0; + + default: + self->errormsg = "Unknown authentication type"; + self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; + return 0; + } + break; + default: + self->errormsg = "Unexpected protocol character during authentication"; + self->errornumber = CONN_INVALID_AUTHENTICATION; + return 0; } - break; - default: - self->errormsg = "Unexpected protocol character during authentication"; - self->errornumber = CONN_INVALID_AUTHENTICATION; - return 0; - } - } while (areq != AUTH_REQ_OK); + } while (areq != AUTH_REQ_OK); - CC_clear_error(self); /* clear any password error */ + CC_clear_error(self); /* clear any password error */ /* send an empty query in order to find out whether the specified */ /* database really exists on the server machine */ mylog("sending an empty query...\n"); res = CC_send_query(self, " ", NULL); - if ( res == NULL || QR_get_status(res) != PGRES_EMPTY_QUERY) { + if (res == NULL || QR_get_status(res) != PGRES_EMPTY_QUERY) + { mylog("got no result from the empty query. (probably database does not exist)\n"); self->errornumber = CONNECTION_NO_SUCH_DATABASE; self->errormsg = "The database does not exist on the server\nor user authentication failed."; @@ -712,21 +763,25 @@ static char *func="CC_connect"; mylog("empty query seems to be OK.\n"); - CC_set_translation (self); + CC_set_translation(self); /**********************************************/ /******* Send any initial settings *********/ /**********************************************/ - /* Since these functions allocate statements, and since the connection is not - established yet, it would violate odbc state transition rules. Therefore, - these functions call the corresponding local function instead. - */ + /* + * Since these functions allocate statements, and since the connection + * is not established yet, it would violate odbc state transition + * rules. Therefore, these functions call the corresponding local + * function instead. + */ CC_send_settings(self); - CC_lookup_lo(self); /* a hack to get the oid of our large object oid type */ - CC_lookup_pg_version(self); /* Get PostgreSQL version for SQLGetInfo use */ + CC_lookup_lo(self); /* a hack to get the oid of our large + * object oid type */ + CC_lookup_pg_version(self); /* Get PostgreSQL version for SQLGetInfo + * use */ - CC_clear_error(self); /* clear any initial command errors */ + CC_clear_error(self); /* clear any initial command errors */ self->status = CONN_CONNECTED; mylog("%s: returning...\n", func); @@ -738,12 +793,14 @@ static char *func="CC_connect"; char CC_add_statement(ConnectionClass *self, StatementClass *stmt) { -int i; + int i; mylog("CC_add_statement: self=%u, stmt=%u\n", self, stmt); - for (i = 0; i < self->num_stmts; i++) { - if ( ! self->stmts[i]) { + for (i = 0; i < self->num_stmts; i++) + { + if (!self->stmts[i]) + { stmt->hdbc = self; self->stmts[i] = stmt; return TRUE; @@ -751,8 +808,8 @@ int i; } /* no more room -- allocate more memory */ - self->stmts = (StatementClass **) realloc( self->stmts, sizeof(StatementClass *) * (STMT_INCREMENT + self->num_stmts)); - if ( ! self->stmts) + self->stmts = (StatementClass **) realloc(self->stmts, sizeof(StatementClass *) * (STMT_INCREMENT + self->num_stmts)); + if (!self->stmts) return FALSE; memset(&self->stmts[self->num_stmts], 0, sizeof(StatementClass *) * STMT_INCREMENT); @@ -765,13 +822,15 @@ int i; return TRUE; } -char +char CC_remove_statement(ConnectionClass *self, StatementClass *stmt) { -int i; + int i; - for (i = 0; i < self->num_stmts; i++) { - if (self->stmts[i] == stmt && stmt->status != STMT_EXECUTING) { + for (i = 0; i < self->num_stmts; i++) + { + if (self->stmts[i] == stmt && stmt->status != STMT_EXECUTING) + { self->stmts[i] = NULL; return TRUE; } @@ -786,9 +845,9 @@ int i; char * CC_create_errormsg(ConnectionClass *self) { -SocketClass *sock = self->sock; -int pos; -static char msg[4096]; + SocketClass *sock = self->sock; + int pos; + static char msg[4096]; mylog("enter CC_create_errormsg\n"); @@ -799,7 +858,8 @@ static char msg[4096]; mylog("msg = '%s'\n", msg); - if (sock && sock->errormsg && sock->errormsg[0] != '\0') { + if (sock && sock->errormsg && sock->errormsg[0] != '\0') + { pos = strlen(msg); sprintf(&msg[pos], ";\n%s", sock->errormsg); } @@ -809,20 +869,22 @@ static char msg[4096]; } -char +char CC_get_error(ConnectionClass *self, int *number, char **message) { -int rv; + int rv; mylog("enter CC_get_error\n"); - /* Create a very informative errormsg if it hasn't been done yet. */ - if ( ! self->errormsg_created) { + /* Create a very informative errormsg if it hasn't been done yet. */ + if (!self->errormsg_created) + { self->errormsg = CC_create_errormsg(self); self->errormsg_created = TRUE; } - if (self->errornumber) { + if (self->errornumber) + { *number = self->errornumber; *message = self->errormsg; } @@ -841,25 +903,29 @@ int rv; needs to be re-filled). The "cursor" is used by SQLExecute to associate a statement handle as the cursor name - (i.e., C3326857) for SQL select statements. This cursor is then used in future + (i.e., C3326857) for SQL select statements. This cursor is then used in future 'declare cursor C3326857 for ...' and 'fetch 100 in C3326857' statements. */ QResultClass * CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) { -QResultClass *result_in, *res = NULL; -char swallow; -int id; -SocketClass *sock = self->sock; -static char msgbuffer[MAX_MESSAGE_LEN+1]; -char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont need static */ + QResultClass *result_in, + *res = NULL; + char swallow; + int id; + SocketClass *sock = self->sock; + static char msgbuffer[MAX_MESSAGE_LEN + 1]; + char cmdbuffer[MAX_MESSAGE_LEN + 1]; /* QR_set_command() dups + * this string so dont + * need static */ mylog("send_query(): conn=%u, query='%s'\n", self, query); qlog("conn=%u, query='%s'\n", self, query); /* Indicate that we are sending a query to the backend */ - if(strlen(query) > MAX_MESSAGE_LEN-2) { + if (strlen(query) > MAX_MESSAGE_LEN - 2) + { self->errornumber = CONNECTION_MSG_TOO_LONG; self->errormsg = "Query string is too long"; return NULL; @@ -868,7 +934,8 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont if ((NULL == query) || (query[0] == '\0')) return NULL; - if (SOCK_get_errcode(sock) != 0) { + if (SOCK_get_errcode(sock) != 0) + { self->errornumber = CONNECTION_COULD_NOT_SEND; self->errormsg = "Could not send Query to backend"; CC_set_no_trans(self); @@ -876,7 +943,8 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont } SOCK_put_char(sock, 'Q'); - if (SOCK_get_errcode(sock) != 0) { + if (SOCK_get_errcode(sock) != 0) + { self->errornumber = CONNECTION_COULD_NOT_SEND; self->errormsg = "Could not send Query to backend"; CC_set_no_trans(self); @@ -886,7 +954,8 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont SOCK_put_string(sock, query); SOCK_flush_output(sock); - if (SOCK_get_errcode(sock) != 0) { + if (SOCK_get_errcode(sock) != 0) + { self->errornumber = CONNECTION_COULD_NOT_SEND; self->errormsg = "Could not send Query to backend"; CC_set_no_trans(self); @@ -895,11 +964,13 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont mylog("send_query: done sending query\n"); - while(1) { + while (1) + { /* what type of message is coming now ? */ id = SOCK_get_char(sock); - if ((SOCK_get_errcode(sock) != 0) || (id == EOF)) { + if ((SOCK_get_errcode(sock) != 0) || (id == EOF)) + { self->errornumber = CONNECTION_NO_RESPONSE; self->errormsg = "No response from the backend"; if (res) @@ -912,199 +983,222 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont mylog("send_query: got id = '%c'\n", id); - switch (id) { - case 'A' : /* Asynchronous Messages are ignored */ - (void)SOCK_get_int(sock, 4); /* id of notification */ - SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN); - /* name of the relation the message comes from */ - break; - case 'C' : /* portal query command, no tuples returned */ - /* read in the return message from the backend */ - SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN); - if (SOCK_get_errcode(sock) != 0) { - self->errornumber = CONNECTION_NO_RESPONSE; - self->errormsg = "No response from backend while receiving a portal query command"; - mylog("send_query: 'C' - %s\n", self->errormsg); - CC_set_no_trans(self); - return NULL; - } else { - - char clear = 0; - - mylog("send_query: ok - 'C' - %s\n", cmdbuffer); - - if (res == NULL) /* allow for "show" style notices */ - res = QR_Constructor(); - - mylog("send_query: setting cmdbuffer = '%s'\n", cmdbuffer); - - /* Only save the first command */ - QR_set_status(res, PGRES_COMMAND_OK); - QR_set_command(res, cmdbuffer); - - /* (Quotation from the original comments) - since backend may produce more than one result for some commands - we need to poll until clear - so we send an empty query, and keep reading out of the pipe - until an 'I' is received - */ - - - SOCK_put_string(sock, "Q "); - SOCK_flush_output(sock); - - while( ! clear) { - id = SOCK_get_char(sock); - switch(id) { - case 'I': - (void) SOCK_get_char(sock); - clear = TRUE; - break; - case 'Z': - break; - case 'C': - SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - qlog("Command response: '%s'\n", cmdbuffer); - break; - case 'N': - SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - qlog("NOTICE from backend during clear: '%s'\n", cmdbuffer); - break; - case 'E': - SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - qlog("ERROR from backend during clear: '%s'\n", cmdbuffer); - /* We must report this type of error as well - (practically for reference integrity violation - error reporting, from PostgreSQL 7.0). - (Zoltan Kovacs, 04/26/2000) - */ - self->errormsg = cmdbuffer; - if ( ! strncmp(self->errormsg, "FATAL", 5)) { - self->errornumber = CONNECTION_SERVER_REPORTED_ERROR; - CC_set_no_trans(self); - } - else - self->errornumber = CONNECTION_SERVER_REPORTED_WARNING; - QR_set_status(res, PGRES_NONFATAL_ERROR); - QR_set_aborted(res, TRUE); - break; + switch (id) + { + case 'A': /* Asynchronous Messages are ignored */ + (void) SOCK_get_int(sock, 4); /* id of notification */ + SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN); + /* name of the relation the message comes from */ + break; + case 'C': /* portal query command, no tuples + * returned */ + /* read in the return message from the backend */ + SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN); + if (SOCK_get_errcode(sock) != 0) + { + self->errornumber = CONNECTION_NO_RESPONSE; + self->errormsg = "No response from backend while receiving a portal query command"; + mylog("send_query: 'C' - %s\n", self->errormsg); + CC_set_no_trans(self); + return NULL; + } + else + { + + char clear = 0; + + mylog("send_query: ok - 'C' - %s\n", cmdbuffer); + + if (res == NULL) /* allow for "show" style notices */ + res = QR_Constructor(); + + mylog("send_query: setting cmdbuffer = '%s'\n", cmdbuffer); + + /* Only save the first command */ + QR_set_status(res, PGRES_COMMAND_OK); + QR_set_command(res, cmdbuffer); + + /* + * (Quotation from the original comments) since + * backend may produce more than one result for some + * commands we need to poll until clear so we send an + * empty query, and keep reading out of the pipe until + * an 'I' is received + */ + + + SOCK_put_string(sock, "Q "); + SOCK_flush_output(sock); + + while (!clear) + { + id = SOCK_get_char(sock); + switch (id) + { + case 'I': + (void) SOCK_get_char(sock); + clear = TRUE; + break; + case 'Z': + break; + case 'C': + SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); + qlog("Command response: '%s'\n", cmdbuffer); + break; + case 'N': + SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); + qlog("NOTICE from backend during clear: '%s'\n", cmdbuffer); + break; + case 'E': + SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); + qlog("ERROR from backend during clear: '%s'\n", cmdbuffer); + + /* + * We must report this type of error as + * well (practically for reference + * integrity violation error reporting, + * from PostgreSQL 7.0). (Zoltan Kovacs, + * 04/26/2000) + */ + self->errormsg = cmdbuffer; + if (!strncmp(self->errormsg, "FATAL", 5)) + { + self->errornumber = CONNECTION_SERVER_REPORTED_ERROR; + CC_set_no_trans(self); + } + else + self->errornumber = CONNECTION_SERVER_REPORTED_WARNING; + QR_set_status(res, PGRES_NONFATAL_ERROR); + QR_set_aborted(res, TRUE); + break; + } } + + mylog("send_query: returning res = %u\n", res); + return res; } - - mylog("send_query: returning res = %u\n", res); - return res; - } - case 'K': /* Secret key (6.4 protocol) */ - (void)SOCK_get_int(sock, 4); /* pid */ - (void)SOCK_get_int(sock, 4); /* key */ + case 'K': /* Secret key (6.4 protocol) */ + (void) SOCK_get_int(sock, 4); /* pid */ + (void) SOCK_get_int(sock, 4); /* key */ - break; - case 'Z': /* Backend is ready for new query (6.4) */ - break; - case 'N' : /* NOTICE: */ - SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); + break; + case 'Z': /* Backend is ready for new query (6.4) */ + break; + case 'N': /* NOTICE: */ + SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH); - res = QR_Constructor(); - QR_set_status(res, PGRES_NONFATAL_ERROR); - QR_set_notice(res, cmdbuffer); /* will dup this string */ + res = QR_Constructor(); + QR_set_status(res, PGRES_NONFATAL_ERROR); + QR_set_notice(res, cmdbuffer); /* will dup this string */ - mylog("~~~ NOTICE: '%s'\n", cmdbuffer); - qlog("NOTICE from backend during send_query: '%s'\n", cmdbuffer); + mylog("~~~ NOTICE: '%s'\n", cmdbuffer); + qlog("NOTICE from backend during send_query: '%s'\n", cmdbuffer); - continue; /* dont return a result -- continue reading */ + continue; /* dont return a result -- continue + * reading */ - case 'I' : /* The server sends an empty query */ + case 'I': /* The server sends an empty query */ /* There is a closing '\0' following the 'I', so we eat it */ - swallow = SOCK_get_char(sock); - if ((swallow != '\0') || SOCK_get_errcode(sock) != 0) { - self->errornumber = CONNECTION_BACKEND_CRAZY; - self->errormsg = "Unexpected protocol character from backend (send_query - I)"; - res = QR_Constructor(); - QR_set_status(res, PGRES_FATAL_ERROR); - return res; - } else { - /* We return the empty query */ - res = QR_Constructor(); - QR_set_status(res, PGRES_EMPTY_QUERY); - return res; - } - break; - case 'E' : - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); + swallow = SOCK_get_char(sock); + if ((swallow != '\0') || SOCK_get_errcode(sock) != 0) + { + self->errornumber = CONNECTION_BACKEND_CRAZY; + self->errormsg = "Unexpected protocol character from backend (send_query - I)"; + res = QR_Constructor(); + QR_set_status(res, PGRES_FATAL_ERROR); + return res; + } + else + { + /* We return the empty query */ + res = QR_Constructor(); + QR_set_status(res, PGRES_EMPTY_QUERY); + return res; + } + break; + case 'E': + SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - /* Remove a newline */ - if (msgbuffer[0] != '\0' && msgbuffer[strlen(msgbuffer)-1] == '\n') - msgbuffer[strlen(msgbuffer)-1] = '\0'; + /* Remove a newline */ + if (msgbuffer[0] != '\0' && msgbuffer[strlen(msgbuffer) - 1] == '\n') + msgbuffer[strlen(msgbuffer) - 1] = '\0'; - self->errormsg = msgbuffer; + self->errormsg = msgbuffer; - mylog("send_query: 'E' - %s\n", self->errormsg); - qlog("ERROR from backend during send_query: '%s'\n", self->errormsg); + mylog("send_query: 'E' - %s\n", self->errormsg); + qlog("ERROR from backend during send_query: '%s'\n", self->errormsg); - /* We should report that an error occured. Zoltan */ - res = QR_Constructor(); + /* We should report that an error occured. Zoltan */ + res = QR_Constructor(); - if ( ! strncmp(self->errormsg, "FATAL", 5)) { - self->errornumber = CONNECTION_SERVER_REPORTED_ERROR; - CC_set_no_trans(self); - QR_set_status(res, PGRES_FATAL_ERROR); - } - else { - self->errornumber = CONNECTION_SERVER_REPORTED_WARNING; - QR_set_status(res, PGRES_NONFATAL_ERROR); - } - QR_set_aborted(res, TRUE); - - return res; /* instead of NULL. Zoltan */ - - case 'P' : /* get the Portal name */ - SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN); - break; - case 'T': /* Tuple results start here */ - result_in = qi ? qi->result_in : NULL; - - if ( result_in == NULL) { - result_in = QR_Constructor(); - mylog("send_query: 'T' no result_in: res = %u\n", result_in); - if ( ! result_in) { - self->errornumber = CONNECTION_COULD_NOT_RECEIVE; - self->errormsg = "Could not create result info in send_query."; - return NULL; + if (!strncmp(self->errormsg, "FATAL", 5)) + { + self->errornumber = CONNECTION_SERVER_REPORTED_ERROR; + CC_set_no_trans(self); + QR_set_status(res, PGRES_FATAL_ERROR); } + else + { + self->errornumber = CONNECTION_SERVER_REPORTED_WARNING; + QR_set_status(res, PGRES_NONFATAL_ERROR); + } + QR_set_aborted(res, TRUE); - if (qi) - QR_set_cache_size(result_in, qi->row_size); + return res; /* instead of NULL. Zoltan */ - if ( ! QR_fetch_tuples(result_in, self, qi ? qi->cursor : NULL)) { - self->errornumber = CONNECTION_COULD_NOT_RECEIVE; - self->errormsg = QR_get_message(result_in); - return NULL; + case 'P': /* get the Portal name */ + SOCK_get_string(sock, msgbuffer, MAX_MESSAGE_LEN); + break; + case 'T': /* Tuple results start here */ + result_in = qi ? qi->result_in : NULL; + + if (result_in == NULL) + { + result_in = QR_Constructor(); + mylog("send_query: 'T' no result_in: res = %u\n", result_in); + if (!result_in) + { + self->errornumber = CONNECTION_COULD_NOT_RECEIVE; + self->errormsg = "Could not create result info in send_query."; + return NULL; + } + + if (qi) + QR_set_cache_size(result_in, qi->row_size); + + if (!QR_fetch_tuples(result_in, self, qi ? qi->cursor : NULL)) + { + self->errornumber = CONNECTION_COULD_NOT_RECEIVE; + self->errormsg = QR_get_message(result_in); + return NULL; + } } - } - else { /* next fetch, so reuse an existing result */ - if ( ! QR_fetch_tuples(result_in, NULL, NULL)) { - self->errornumber = CONNECTION_COULD_NOT_RECEIVE; - self->errormsg = QR_get_message(result_in); - return NULL; + else + { /* next fetch, so reuse an existing result */ + if (!QR_fetch_tuples(result_in, NULL, NULL)) + { + self->errornumber = CONNECTION_COULD_NOT_RECEIVE; + self->errormsg = QR_get_message(result_in); + return NULL; + } } - } - return result_in; - case 'D': /* Copy in command began successfully */ - res = QR_Constructor(); - QR_set_status(res, PGRES_COPY_IN); - return res; - case 'B': /* Copy out command began successfully */ - res = QR_Constructor(); - QR_set_status(res, PGRES_COPY_OUT); - return res; - default: - self->errornumber = CONNECTION_BACKEND_CRAZY; - self->errormsg = "Unexpected protocol character from backend (send_query)"; - CC_set_no_trans(self); + return result_in; + case 'D': /* Copy in command began successfully */ + res = QR_Constructor(); + QR_set_status(res, PGRES_COPY_IN); + return res; + case 'B': /* Copy out command began successfully */ + res = QR_Constructor(); + QR_set_status(res, PGRES_COPY_OUT); + return res; + default: + self->errornumber = CONNECTION_BACKEND_CRAZY; + self->errormsg = "Unexpected protocol character from backend (send_query)"; + CC_set_no_trans(self); - mylog("send_query: error - %s\n", self->errormsg); - return NULL; + mylog("send_query: error - %s\n", self->errormsg); + return NULL; } } } @@ -1112,14 +1206,17 @@ char cmdbuffer[MAX_MESSAGE_LEN+1]; /* QR_set_command() dups this string so dont int CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *args, int nargs) { -char id, c, done; -SocketClass *sock = self->sock; -static char msgbuffer[MAX_MESSAGE_LEN+1]; -int i; + char id, + c, + done; + SocketClass *sock = self->sock; + static char msgbuffer[MAX_MESSAGE_LEN + 1]; + int i; mylog("send_function(): conn=%u, fnid=%d, result_is_int=%d, nargs=%d\n", self, fnid, result_is_int, nargs); - if (SOCK_get_errcode(sock) != 0) { + if (SOCK_get_errcode(sock) != 0) + { self->errornumber = CONNECTION_COULD_NOT_SEND; self->errormsg = "Could not send function to backend"; CC_set_no_trans(self); @@ -1127,25 +1224,27 @@ int i; } SOCK_put_string(sock, "F "); - if (SOCK_get_errcode(sock) != 0) { + if (SOCK_get_errcode(sock) != 0) + { self->errornumber = CONNECTION_COULD_NOT_SEND; self->errormsg = "Could not send function to backend"; CC_set_no_trans(self); return FALSE; } - SOCK_put_int(sock, fnid, 4); - SOCK_put_int(sock, nargs, 4); + SOCK_put_int(sock, fnid, 4); + SOCK_put_int(sock, nargs, 4); mylog("send_function: done sending function\n"); - for (i = 0; i < nargs; ++i) { + for (i = 0; i < nargs; ++i) + { mylog(" arg[%d]: len = %d, isint = %d, integer = %d, ptr = %u\n", i, args[i].len, args[i].isint, args[i].u.integer, args[i].u.ptr); SOCK_put_int(sock, args[i].len, 4); - if (args[i].isint) + if (args[i].isint) SOCK_put_int(sock, args[i].u.integer, 4); else SOCK_put_n_char(sock, (char *) args[i].u.ptr, args[i].len); @@ -1159,92 +1258,97 @@ int i; mylog(" after flush output\n"); done = FALSE; - while ( ! done) { + while (!done) + { id = SOCK_get_char(sock); mylog(" got id = %c\n", id); - switch(id) { - case 'V': - done = TRUE; - break; /* ok */ + switch (id) + { + case 'V': + done = TRUE; + break; /* ok */ - case 'N': - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - mylog("send_function(V): 'N' - %s\n", msgbuffer); - /* continue reading */ - break; + case 'N': + SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); + mylog("send_function(V): 'N' - %s\n", msgbuffer); + /* continue reading */ + break; - case 'E': - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - self->errormsg = msgbuffer; + case 'E': + SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); + self->errormsg = msgbuffer; - mylog("send_function(V): 'E' - %s\n", self->errormsg); - qlog("ERROR from backend during send_function: '%s'\n", self->errormsg); + mylog("send_function(V): 'E' - %s\n", self->errormsg); + qlog("ERROR from backend during send_function: '%s'\n", self->errormsg); - return FALSE; + return FALSE; - case 'Z': - break; + case 'Z': + break; - default: - self->errornumber = CONNECTION_BACKEND_CRAZY; - self->errormsg = "Unexpected protocol character from backend (send_function, args)"; - CC_set_no_trans(self); + default: + self->errornumber = CONNECTION_BACKEND_CRAZY; + self->errormsg = "Unexpected protocol character from backend (send_function, args)"; + CC_set_no_trans(self); - mylog("send_function: error - %s\n", self->errormsg); - return FALSE; + mylog("send_function: error - %s\n", self->errormsg); + return FALSE; } } id = SOCK_get_char(sock); - for (;;) { - switch (id) { - case 'G': /* function returned properly */ - mylog(" got G!\n"); + for (;;) + { + switch (id) + { + case 'G': /* function returned properly */ + mylog(" got G!\n"); - *actual_result_len = SOCK_get_int(sock, 4); - mylog(" actual_result_len = %d\n", *actual_result_len); + *actual_result_len = SOCK_get_int(sock, 4); + mylog(" actual_result_len = %d\n", *actual_result_len); - if (result_is_int) - *((int *) result_buf) = SOCK_get_int(sock, 4); - else - SOCK_get_n_char(sock, (char *) result_buf, *actual_result_len); + if (result_is_int) + *((int *) result_buf) = SOCK_get_int(sock, 4); + else + SOCK_get_n_char(sock, (char *) result_buf, *actual_result_len); - mylog(" after get result\n"); + mylog(" after get result\n"); - c = SOCK_get_char(sock); /* get the last '0' */ + c = SOCK_get_char(sock); /* get the last '0' */ - mylog(" after get 0\n"); + mylog(" after get 0\n"); - return TRUE; + return TRUE; - case 'E': - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - self->errormsg = msgbuffer; + case 'E': + SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); + self->errormsg = msgbuffer; - mylog("send_function(G): 'E' - %s\n", self->errormsg); - qlog("ERROR from backend during send_function: '%s'\n", self->errormsg); + mylog("send_function(G): 'E' - %s\n", self->errormsg); + qlog("ERROR from backend during send_function: '%s'\n", self->errormsg); - return FALSE; + return FALSE; - case 'N': - SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); + case 'N': + SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH); - mylog("send_function(G): 'N' - %s\n", msgbuffer); - qlog("NOTICE from backend during send_function: '%s'\n", msgbuffer); + mylog("send_function(G): 'N' - %s\n", msgbuffer); + qlog("NOTICE from backend during send_function: '%s'\n", msgbuffer); - continue; /* dont return a result -- continue reading */ + continue; /* dont return a result -- continue + * reading */ - case '0': /* empty result */ - return TRUE; + case '0': /* empty result */ + return TRUE; - default: - self->errornumber = CONNECTION_BACKEND_CRAZY; - self->errormsg = "Unexpected protocol character from backend (send_function, result)"; - CC_set_no_trans(self); + default: + self->errornumber = CONNECTION_BACKEND_CRAZY; + self->errormsg = "Unexpected protocol character from backend (send_function, result)"; + CC_set_no_trans(self); - mylog("send_function: error - %s\n", self->errormsg); - return FALSE; + mylog("send_function: error - %s\n", self->errormsg); + return FALSE; } } } @@ -1253,65 +1357,70 @@ int i; char CC_send_settings(ConnectionClass *self) { - /* char ini_query[MAX_MESSAGE_LEN]; */ -ConnInfo *ci = &(self->connInfo); + /* char ini_query[MAX_MESSAGE_LEN]; */ + ConnInfo *ci = &(self->connInfo); + /* QResultClass *res; */ -HSTMT hstmt; -StatementClass *stmt; -RETCODE result; -char status = TRUE; -char *cs, *ptr; -static char *func="CC_send_settings"; + HSTMT hstmt; + StatementClass *stmt; + RETCODE result; + char status = TRUE; + char *cs, + *ptr; + static char *func = "CC_send_settings"; mylog("%s: entering...\n", func); -/* This function must use the local odbc API functions since the odbc state +/* This function must use the local odbc API functions since the odbc state has not transitioned to "connected" yet. */ - result = SQLAllocStmt( self, &hstmt); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + result = SQLAllocStmt(self, &hstmt); + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) return FALSE; - } stmt = (StatementClass *) hstmt; - stmt->internal = TRUE; /* ensure no BEGIN/COMMIT/ABORT stuff */ + stmt->internal = TRUE; /* ensure no BEGIN/COMMIT/ABORT stuff */ - /* Set the Datestyle to the format the driver expects it to be in */ + /* Set the Datestyle to the format the driver expects it to be in */ result = SQLExecDirect(hstmt, "set DateStyle to 'ISO'", SQL_NTS); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; mylog("%s: result %d, status %d from set DateStyle\n", func, result, status); - /* Disable genetic optimizer based on global flag */ - if (globals.disable_optimizer) { + /* Disable genetic optimizer based on global flag */ + if (globals.disable_optimizer) + { result = SQLExecDirect(hstmt, "set geqo to 'OFF'", SQL_NTS); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; mylog("%s: result %d, status %d from set geqo\n", func, result, status); - + } - /* KSQO */ - if (globals.ksqo) { + /* KSQO */ + if (globals.ksqo) + { result = SQLExecDirect(hstmt, "set ksqo to 'ON'", SQL_NTS); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; mylog("%s: result %d, status %d from set ksqo\n", func, result, status); - + } - /* Global settings */ - if (globals.conn_settings[0] != '\0') { + /* Global settings */ + if (globals.conn_settings[0] != '\0') + { cs = strdup(globals.conn_settings); ptr = strtok(cs, ";"); - while (ptr) { + while (ptr) + { result = SQLExecDirect(hstmt, ptr, SQL_NTS); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; mylog("%s: result %d, status %d from '%s'\n", func, result, status, ptr); @@ -1321,14 +1430,16 @@ static char *func="CC_send_settings"; free(cs); } - - /* Per Datasource settings */ - if (ci->conn_settings[0] != '\0') { + + /* Per Datasource settings */ + if (ci->conn_settings[0] != '\0') + { cs = strdup(ci->conn_settings); ptr = strtok(cs, ";"); - while (ptr) { + while (ptr) + { result = SQLExecDirect(hstmt, ptr, SQL_NTS); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; mylog("%s: result %d, status %d from '%s'\n", func, result, status, ptr); @@ -1350,38 +1461,40 @@ static char *func="CC_send_settings"; will go away and the define 'PG_TYPE_LO' will be updated. */ void -CC_lookup_lo(ConnectionClass *self) +CC_lookup_lo(ConnectionClass *self) { -HSTMT hstmt; -StatementClass *stmt; -RETCODE result; -static char *func = "CC_lookup_lo"; + HSTMT hstmt; + StatementClass *stmt; + RETCODE result; + static char *func = "CC_lookup_lo"; - mylog( "%s: entering...\n", func); + mylog("%s: entering...\n", func); -/* This function must use the local odbc API functions since the odbc state +/* This function must use the local odbc API functions since the odbc state has not transitioned to "connected" yet. */ - result = SQLAllocStmt( self, &hstmt); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + result = SQLAllocStmt(self, &hstmt); + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) return; - } stmt = (StatementClass *) hstmt; result = SQLExecDirect(hstmt, "select oid from pg_type where typname='" PG_TYPE_LO_NAME "'", SQL_NTS); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { SQLFreeStmt(hstmt, SQL_DROP); return; } result = SQLFetch(hstmt); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { SQLFreeStmt(hstmt, SQL_DROP); return; } result = SQLGetData(hstmt, 1, SQL_C_SLONG, &self->lobj_type, sizeof(self->lobj_type), NULL); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { SQLFreeStmt(hstmt, SQL_DROP); return; } @@ -1397,63 +1510,72 @@ static char *func = "CC_lookup_lo"; h-inoue 01-2-2001 */ void -CC_initialize_pg_version(ConnectionClass *self) +CC_initialize_pg_version(ConnectionClass *self) { - strcpy(self->pg_version, self->connInfo.protocol); - if (PROTOCOL_62(&self->connInfo)) { + strcpy(self->pg_version, self->connInfo.protocol); + if (PROTOCOL_62(&self->connInfo)) + { self->pg_version_number = (float) 6.2; self->pg_version_major = 6; self->pg_version_minor = 2; - } else if (PROTOCOL_63(&self->connInfo)) { + } + else if (PROTOCOL_63(&self->connInfo)) + { self->pg_version_number = (float) 6.3; self->pg_version_major = 6; self->pg_version_minor = 3; - } else { + } + else + { self->pg_version_number = (float) 6.4; self->pg_version_major = 6; self->pg_version_minor = 4; } } + /* This function gets the version of PostgreSQL that we're connected to. - This is used to return the correct info in SQLGetInfo + This is used to return the correct info in SQLGetInfo DJP - 25-1-2001 */ void -CC_lookup_pg_version(ConnectionClass *self) +CC_lookup_pg_version(ConnectionClass *self) { -HSTMT hstmt; -StatementClass *stmt; -RETCODE result; -char szVersion[32]; -int major, minor; -static char *func = "CC_lookup_pg_version"; + HSTMT hstmt; + StatementClass *stmt; + RETCODE result; + char szVersion[32]; + int major, + minor; + static char *func = "CC_lookup_pg_version"; - mylog( "%s: entering...\n", func); + mylog("%s: entering...\n", func); -/* This function must use the local odbc API functions since the odbc state +/* This function must use the local odbc API functions since the odbc state has not transitioned to "connected" yet. */ - result = SQLAllocStmt( self, &hstmt); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + result = SQLAllocStmt(self, &hstmt); + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) return; - } stmt = (StatementClass *) hstmt; - /* get the server's version if possible */ + /* get the server's version if possible */ result = SQLExecDirect(hstmt, "select version()", SQL_NTS); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { SQLFreeStmt(hstmt, SQL_DROP); return; } result = SQLFetch(hstmt); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { SQLFreeStmt(hstmt, SQL_DROP); return; } result = SQLGetData(hstmt, 1, SQL_C_CHAR, self->pg_version, MAX_INFO_STRING, NULL); - if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + { SQLFreeStmt(hstmt, SQL_DROP); return; } @@ -1461,7 +1583,8 @@ static char *func = "CC_lookup_pg_version"; /* Extract the Major and Minor numbers from the string. */ /* This assumes the string starts 'Postgresql X.X' */ strcpy(szVersion, "0.0"); - if (sscanf(self->pg_version, "%*s %d.%d", &major, &minor) >= 2) { + if (sscanf(self->pg_version, "%*s %d.%d", &major, &minor) >= 2) + { sprintf(szVersion, "%d.%d", major, minor); self->pg_version_major = major; self->pg_version_minor = minor; @@ -1483,23 +1606,25 @@ CC_log_error(char *func, char *desc, ConnectionClass *self) #define nullcheck(a) (a ? a : "(NULL)") #endif - if (self) { - qlog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck (self->errormsg)); - mylog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck (self->errormsg)); + if (self) + { + qlog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg)); + mylog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg)); qlog(" ------------------------------------------------------------\n"); qlog(" henv=%u, conn=%u, status=%u, num_stmts=%d\n", self->henv, self, self->status, self->num_stmts); qlog(" sock=%u, stmts=%u, lobj_type=%d\n", self->sock, self->stmts, self->lobj_type); qlog(" ---------------- Socket Info -------------------------------\n"); - if (self->sock) { - SocketClass *sock = self->sock; - qlog(" socket=%d, reverse=%d, errornumber=%d, errormsg='%s'\n", sock->socket, sock->reverse, sock->errornumber, nullcheck(sock->errormsg)); - qlog(" buffer_in=%u, buffer_out=%u\n", sock->buffer_in, sock->buffer_out); - qlog(" buffer_filled_in=%d, buffer_filled_out=%d, buffer_read_in=%d\n", sock->buffer_filled_in, sock->buffer_filled_out, sock->buffer_read_in); + if (self->sock) + { + SocketClass *sock = self->sock; + + qlog(" socket=%d, reverse=%d, errornumber=%d, errormsg='%s'\n", sock->socket, sock->reverse, sock->errornumber, nullcheck(sock->errormsg)); + qlog(" buffer_in=%u, buffer_out=%u\n", sock->buffer_in, sock->buffer_out); + qlog(" buffer_filled_in=%d, buffer_filled_out=%d, buffer_read_in=%d\n", sock->buffer_filled_in, sock->buffer_filled_out, sock->buffer_read_in); } } else qlog("INVALID CONNECTION HANDLE ERROR: func=%s, desc='%s'\n", func, desc); #undef PRN_NULLCHECK } - |