bool ECPGdisconnect(int lineno, const char *connection_name) { struct sqlca_t *sqlca = ECPGget_sqlca(); struct connection *con; if (sqlca == NULL) { ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL); return (false); } #ifdef ENABLE_THREAD_SAFETY pthread_mutex_lock(&connections_mutex); #endif if (strcmp(connection_name, "ALL") == 0) { ecpg_init_sqlca(sqlca); for (con = all_connections; con;) { struct connection *f = con; con = con->next; ecpg_finish(f); } } else { con = ecpg_get_connection_nr(connection_name); if (!ecpg_init(con, connection_name, lineno)) { #ifdef ENABLE_THREAD_SAFETY pthread_mutex_unlock(&connections_mutex); #endif return (false); } else ecpg_finish(con); } #ifdef ENABLE_THREAD_SAFETY pthread_mutex_unlock(&connections_mutex); #endif return true; }
/* this contains some quick hacks, needs to be cleaned up, but it works */ bool ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit) { struct sqlca_t *sqlca = ECPGget_sqlca(); enum COMPAT_MODE compat = c; struct connection *this; int i; char *dbname = name ? ecpg_strdup(name, lineno) : NULL, *host = NULL, *tmp, *port = NULL, *realname = NULL, *options = NULL, *connect_string = NULL; ecpg_init_sqlca(sqlca); /* * clear auto_mem structure because some error handling functions might * access it */ ecpg_clear_auto_mem(); if (INFORMIX_MODE(compat)) { char *envname; /* * Informix uses an environment variable DBPATH that overrides the * connection parameters given here. We do the same with PG_DBPATH as * the syntax is different. */ envname = getenv("PG_DBPATH"); if (envname) { ecpg_free(dbname); dbname = ecpg_strdup(envname, lineno); } } if (dbname == NULL && connection_name == NULL) connection_name = "DEFAULT"; #if ENABLE_THREAD_SAFETY ecpg_pthreads_init(); #endif /* check if the identifier is unique */ if (ecpg_get_connection(connection_name)) { ecpg_free(dbname); ecpg_log("ECPGconnect: connection identifier %s is already in use\n", connection_name); return false; } if ((this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno)) == NULL) return false; if (dbname != NULL) { /* get the detail information out of dbname */ if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0) { int offset = 0; /* * only allow protocols tcp and unix */ if (strncmp(dbname, "tcp:", 4) == 0) offset = 4; else if (strncmp(dbname, "unix:", 5) == 0) offset = 5; if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0) { /*------ * new style: * <tcp|unix>:postgresql://server[:port|:/unixsocket/path:] * [/db name][?options] *------ */ offset += strlen("postgresql://"); tmp = strrchr(dbname + offset, '?'); if (tmp != NULL) /* options given */ { options = ecpg_strdup(tmp + 1, lineno); *tmp = '\0'; } tmp = last_dir_separator(dbname + offset); if (tmp != NULL) /* database name given */ { if (tmp[1] != '\0') /* non-empty database name */ realname = ecpg_strdup(tmp + 1, lineno); *tmp = '\0'; } tmp = strrchr(dbname + offset, ':'); if (tmp != NULL) /* port number or Unix socket path given */ { char *tmp2; *tmp = '\0'; if ((tmp2 = strchr(tmp + 1, ':')) != NULL) { *tmp2 = '\0'; host = ecpg_strdup(tmp + 1, lineno); if (strncmp(dbname, "unix:", 5) != 0) { ecpg_log("ECPGconnect: socketname %s given for TCP connection on line %d\n", host, lineno); ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : ecpg_gettext("<DEFAULT>")); if (host) ecpg_free(host); /* * port not set yet if (port) ecpg_free(port); */ if (options) ecpg_free(options); if (realname) ecpg_free(realname); if (dbname) ecpg_free(dbname); free(this); return false; } } else port = ecpg_strdup(tmp + 1, lineno); } if (strncmp(dbname, "unix:", 5) == 0) { if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0) { ecpg_log("ECPGconnect: non-localhost access via sockets on line %d\n", lineno); ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : ecpg_gettext("<DEFAULT>")); if (host) ecpg_free(host); if (port) ecpg_free(port); if (options) ecpg_free(options); if (realname) ecpg_free(realname); if (dbname) ecpg_free(dbname); free(this); return false; } } else host = ecpg_strdup(dbname + offset, lineno); } } else { /* old style: dbname[@server][:port] */ tmp = strrchr(dbname, ':'); if (tmp != NULL) /* port number given */ { port = ecpg_strdup(tmp + 1, lineno); *tmp = '\0'; } tmp = strrchr(dbname, '@'); if (tmp != NULL) /* host name given */ { host = ecpg_strdup(tmp + 1, lineno); *tmp = '\0'; } realname = (strlen(dbname) > 0) ? ecpg_strdup(dbname, lineno) : NULL; } } else realname = NULL; /* add connection to our list */ #ifdef ENABLE_THREAD_SAFETY pthread_mutex_lock(&connections_mutex); #endif if (connection_name != NULL) this->name = ecpg_strdup(connection_name, lineno); else this->name = ecpg_strdup(realname, lineno); this->cache_head = NULL; this->prep_stmts = NULL; if (all_connections == NULL) this->next = NULL; else this->next = all_connections; all_connections = this; #ifdef ENABLE_THREAD_SAFETY pthread_setspecific(actual_connection_key, all_connections); #endif actual_connection = all_connections; ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n", realname ? realname : "<DEFAULT>", host ? host : "<DEFAULT>", port ? (ecpg_internal_regression_mode ? "<REGRESSION_PORT>" : port) : "<DEFAULT>", options ? "with options " : "", options ? options : "", (user && strlen(user) > 0) ? "for user " : "", user ? user : ""); connect_string = ecpg_alloc(strlen_or_null(host) + strlen_or_null(port) + strlen_or_null(options) + strlen_or_null(realname) + strlen_or_null(user) + strlen_or_null(passwd) + sizeof(" host = port = dbname = user = password ="******"%s%s %s%s %s%s %s%s %s%s %s", realname ? "dbname=" : "", realname ? realname : "", host ? "host=" : "", host ? host : "", port ? "port=" : "", port ? port : "", (user && strlen(user) > 0) ? "user="******"", user ? user : "", (passwd && strlen(passwd) > 0) ? "password="******"", passwd ? passwd : "", options ? options : ""); /* * this is deprecated this->connection = PQsetdbLogin(host, port, options, * NULL, realname, user, passwd); */ this->connection = PQconnectdb(connect_string); ecpg_free(connect_string); if (host) ecpg_free(host); if (port) ecpg_free(port); if (options) ecpg_free(options); if (dbname) ecpg_free(dbname); if (PQstatus(this->connection) == CONNECTION_BAD) { const char *errmsg = PQerrorMessage(this->connection); const char *db = realname ? realname : ecpg_gettext("<DEFAULT>"); ecpg_log("ECPGconnect: could not open database: %s\n", errmsg); ecpg_finish(this); #ifdef ENABLE_THREAD_SAFETY pthread_mutex_unlock(&connections_mutex); #endif ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db); if (realname) ecpg_free(realname); return false; } if (realname) ecpg_free(realname); #ifdef ENABLE_THREAD_SAFETY pthread_mutex_unlock(&connections_mutex); #endif this->autocommit = autocommit; PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, (void *) this); return true; }
/* this contains some quick hacks, needs to be cleaned up, but it works */ bool ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit) { struct sqlca_t *sqlca = ECPGget_sqlca(); enum COMPAT_MODE compat = c; struct connection *this; int i, connect_params = 0; char *dbname = name ? ecpg_strdup(name, lineno) : NULL, *host = NULL, *tmp, *port = NULL, *realname = NULL, *options = NULL; const char **conn_keywords; const char **conn_values; ecpg_init_sqlca(sqlca); /* * clear auto_mem structure because some error handling functions might * access it */ ecpg_clear_auto_mem(); if (INFORMIX_MODE(compat)) { char *envname; /* * Informix uses an environment variable DBPATH that overrides the * connection parameters given here. We do the same with PG_DBPATH as * the syntax is different. */ envname = getenv("PG_DBPATH"); if (envname) { ecpg_free(dbname); dbname = ecpg_strdup(envname, lineno); } } if (dbname == NULL && connection_name == NULL) connection_name = "DEFAULT"; #if ENABLE_THREAD_SAFETY ecpg_pthreads_init(); #endif /* check if the identifier is unique */ if (ecpg_get_connection(connection_name)) { ecpg_free(dbname); ecpg_log("ECPGconnect: connection identifier %s is already in use\n", connection_name); return false; } if ((this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno)) == NULL) return false; if (dbname != NULL) { /* get the detail information from dbname */ if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0) { int offset = 0; /* * only allow protocols tcp and unix */ if (strncmp(dbname, "tcp:", 4) == 0) offset = 4; else if (strncmp(dbname, "unix:", 5) == 0) offset = 5; if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0) { /*------ * new style: * <tcp|unix>:postgresql://server[:port|:/unixsocket/path:] * [/db-name][?options] *------ */ offset += strlen("postgresql://"); tmp = strrchr(dbname + offset, '?'); if (tmp != NULL) /* options given */ { options = ecpg_strdup(tmp + 1, lineno); *tmp = '\0'; } tmp = last_dir_separator(dbname + offset); if (tmp != NULL) /* database name given */ { if (tmp[1] != '\0') /* non-empty database name */ { realname = ecpg_strdup(tmp + 1, lineno); connect_params++; } *tmp = '\0'; } tmp = strrchr(dbname + offset, ':'); if (tmp != NULL) /* port number or Unix socket path given */ { char *tmp2; *tmp = '\0'; if ((tmp2 = strchr(tmp + 1, ':')) != NULL) { *tmp2 = '\0'; host = ecpg_strdup(tmp + 1, lineno); connect_params++; if (strncmp(dbname, "unix:", 5) != 0) { ecpg_log("ECPGconnect: socketname %s given for TCP connection on line %d\n", host, lineno); ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : ecpg_gettext("<DEFAULT>")); if (host) ecpg_free(host); /* * port not set yet if (port) ecpg_free(port); */ if (options) ecpg_free(options); if (realname) ecpg_free(realname); if (dbname) ecpg_free(dbname); free(this); return false; } } else { port = ecpg_strdup(tmp + 1, lineno); connect_params++; } } if (strncmp(dbname, "unix:", 5) == 0) { if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0) { ecpg_log("ECPGconnect: non-localhost access via sockets on line %d\n", lineno); ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : ecpg_gettext("<DEFAULT>")); if (host) ecpg_free(host); if (port) ecpg_free(port); if (options) ecpg_free(options); if (realname) ecpg_free(realname); if (dbname) ecpg_free(dbname); free(this); return false; } } else { if (*(dbname + offset) != '\0') { host = ecpg_strdup(dbname + offset, lineno); connect_params++; } } } } else { /* old style: dbname[@server][:port] */ tmp = strrchr(dbname, ':'); if (tmp != NULL) /* port number given */ { port = ecpg_strdup(tmp + 1, lineno); connect_params++; *tmp = '\0'; } tmp = strrchr(dbname, '@'); if (tmp != NULL) /* host name given */ { host = ecpg_strdup(tmp + 1, lineno); connect_params++; *tmp = '\0'; } if (strlen(dbname) > 0) { realname = ecpg_strdup(dbname, lineno); connect_params++; } else realname = NULL; } } else realname = NULL; /* add connection to our list */ #ifdef ENABLE_THREAD_SAFETY pthread_mutex_lock(&connections_mutex); #endif if (connection_name != NULL) this->name = ecpg_strdup(connection_name, lineno); else this->name = ecpg_strdup(realname, lineno); this->cache_head = NULL; this->prep_stmts = NULL; if (all_connections == NULL) this->next = NULL; else this->next = all_connections; all_connections = this; #ifdef ENABLE_THREAD_SAFETY pthread_setspecific(actual_connection_key, all_connections); #endif actual_connection = all_connections; ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n", realname ? realname : "<DEFAULT>", host ? host : "<DEFAULT>", port ? (ecpg_internal_regression_mode ? "<REGRESSION_PORT>" : port) : "<DEFAULT>", options ? "with options " : "", options ? options : "", (user && strlen(user) > 0) ? "for user " : "", user ? user : ""); if (options) for (i = 0; options[i]; i++) /* count options */ if (options[i] == '=') connect_params++; if (user && strlen(user) > 0) connect_params++; if (passwd && strlen(passwd) > 0) connect_params++; /* allocate enough space for all connection parameters */ conn_keywords = (const char **) ecpg_alloc((connect_params + 1) * sizeof(char *), lineno); conn_values = (const char **) ecpg_alloc(connect_params * sizeof(char *), lineno); if (conn_keywords == NULL || conn_values == NULL) { if (host) ecpg_free(host); if (port) ecpg_free(port); if (options) ecpg_free(options); if (realname) ecpg_free(realname); if (dbname) ecpg_free(dbname); if (conn_keywords) ecpg_free(conn_keywords); if (conn_values) ecpg_free(conn_values); free(this); return false; } i = 0; if (realname) { conn_keywords[i] = "dbname"; conn_values[i] = realname; i++; } if (host) { conn_keywords[i] = "host"; conn_values[i] = host; i++; } if (port) { conn_keywords[i] = "port"; conn_values[i] = port; i++; } if (user && strlen(user) > 0) { conn_keywords[i] = "user"; conn_values[i] = user; i++; } if (passwd && strlen(passwd) > 0) { conn_keywords[i] = "password"; conn_values[i] = passwd; i++; } if (options) { char *str; /* options look like this "option1 = value1 option2 = value2 ... */ /* we have to break up the string into single options */ for (str = options; *str;) { int e, a; char *token1, *token2; for (token1 = str; *token1 && *token1 == ' '; token1++); for (e = 0; token1[e] && token1[e] != '='; e++); if (token1[e]) /* found "=" */ { token1[e] = '\0'; for (token2 = token1 + e + 1; *token2 && *token2 == ' '; token2++); for (a = 0; token2[a] && token2[a] != '&'; a++); if (token2[a]) /* found "&" => another option follows */ { token2[a] = '\0'; str = token2 + a + 1; } else str = token2 + a; conn_keywords[i] = token1; conn_values[i] = token2; i++; } else /* the parser should not be able to create this invalid option */ str = token1 + e; } } conn_keywords[i] = NULL; /* terminator */ this->connection = PQconnectdbParams(conn_keywords, conn_values, 0); if (host) ecpg_free(host); if (port) ecpg_free(port); if (options) ecpg_free(options); if (dbname) ecpg_free(dbname); ecpg_free(conn_values); ecpg_free(conn_keywords); if (PQstatus(this->connection) == CONNECTION_BAD) { const char *errmsg = PQerrorMessage(this->connection); const char *db = realname ? realname : ecpg_gettext("<DEFAULT>"); ecpg_log("ECPGconnect: could not open database: %s\n", errmsg); ecpg_finish(this); #ifdef ENABLE_THREAD_SAFETY pthread_mutex_unlock(&connections_mutex); #endif ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db); if (realname) ecpg_free(realname); return false; } if (realname) ecpg_free(realname); #ifdef ENABLE_THREAD_SAFETY pthread_mutex_unlock(&connections_mutex); #endif this->autocommit = autocommit; PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, (void *) this); return true; }
/* this contains some quick hacks, needs to be cleaned up, but it works */ bool ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit) { struct sqlca_t *sqlca = ECPGget_sqlca(); enum COMPAT_MODE compat = c; struct connection *this; char *dbname = name ? ECPGstrdup(name, lineno) : NULL, *host = NULL, *tmp, *port = NULL, *realname = NULL, *options = NULL; ECPGinit_sqlca(sqlca); ECPGclear_auto_mem(); if (INFORMIX_MODE(compat)) { char *envname; /* * Informix uses an environment variable DBPATH that overrides the * connection parameters given here. We do the same with PG_DBPATH as * the syntax is different. */ envname = getenv("PG_DBPATH"); if (envname) { ECPGfree(dbname); dbname = ECPGstrdup(envname, lineno); } } if ((this = (struct connection *) ECPGalloc(sizeof(struct connection), lineno)) == NULL) return false; if (dbname == NULL && connection_name == NULL) connection_name = "DEFAULT"; if (dbname != NULL) { /* get the detail information out of dbname */ if (strchr(dbname, '@') != NULL) { /* old style: dbname[@server][:port] */ tmp = strrchr(dbname, ':'); if (tmp != NULL) /* port number given */ { port = ECPGstrdup(tmp + 1, lineno); *tmp = '\0'; } tmp = strrchr(dbname, '@'); if (tmp != NULL) /* host name given */ { host = ECPGstrdup(tmp + 1, lineno); *tmp = '\0'; } realname = ECPGstrdup(dbname, lineno); } else if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0) { int offset = 0; /* * only allow protocols tcp and unix */ if (strncmp(dbname, "tcp:", 4) == 0) offset = 4; else if (strncmp(dbname, "unix:", 5) == 0) offset = 5; if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0) { /*------ * new style: * <tcp|unix>:postgresql://server[:port|:/unixsocket/path:] * [/db name][?options] *------ */ offset += strlen("postgresql://"); tmp = strrchr(dbname + offset, '?'); if (tmp != NULL) /* options given */ { options = ECPGstrdup(tmp + 1, lineno); *tmp = '\0'; } tmp = last_dir_separator(dbname + offset); if (tmp != NULL) /* database name given */ { realname = ECPGstrdup(tmp + 1, lineno); *tmp = '\0'; } tmp = strrchr(dbname + offset, ':'); if (tmp != NULL) /* port number or Unix socket path given */ { char *tmp2; *tmp = '\0'; if ((tmp2 = strchr(tmp + 1, ':')) != NULL) { *tmp2 = '\0'; host = ECPGstrdup(tmp + 1, lineno); if (strncmp(dbname, "unix:", 5) != 0) { ECPGlog("connect: socketname %s given for TCP connection in line %d\n", host, lineno); ECPGraise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : "<DEFAULT>"); if (host) ECPGfree(host); if (port) ECPGfree(port); if (options) ECPGfree(options); if (realname) ECPGfree(realname); if (dbname) ECPGfree(dbname); return false; } } else port = ECPGstrdup(tmp + 1, lineno); } if (strncmp(dbname, "unix:", 5) == 0) { if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0) { ECPGlog("connect: non-localhost access via sockets in line %d\n", lineno); ECPGraise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : "<DEFAULT>"); if (host) ECPGfree(host); if (port) ECPGfree(port); if (options) ECPGfree(options); if (realname) ECPGfree(realname); if (dbname) ECPGfree(dbname); ecpg_finish(this); return false; } } else host = ECPGstrdup(dbname + offset, lineno); } else realname = ECPGstrdup(dbname, lineno); } else realname = ECPGstrdup(dbname, lineno); } else realname = NULL; /* add connection to our list */ #ifdef ENABLE_THREAD_SAFETY pthread_mutex_lock(&connections_mutex); #endif if (connection_name != NULL) this->name = ECPGstrdup(connection_name, lineno); else this->name = ECPGstrdup(realname, lineno); this->cache_head = NULL; if (all_connections == NULL) this->next = NULL; else this->next = all_connections; all_connections = this; #ifdef ENABLE_THREAD_SAFETY pthread_once(&actual_connection_key_once, ecpg_actual_connection_init); pthread_setspecific(actual_connection_key, all_connections); #endif actual_connection = all_connections; ECPGlog("ECPGconnect: opening database %s on %s port %s %s%s%s%s\n", realname ? realname : "<DEFAULT>", host ? host : "<DEFAULT>", port ? port : "<DEFAULT>", options ? "with options " : "", options ? options : "", user ? "for user " : "", user ? user : ""); this->connection = PQsetdbLogin(host, port, options, NULL, realname, user, passwd); if (PQstatus(this->connection) == CONNECTION_BAD) { const char *errmsg = PQerrorMessage(this->connection); char *db = realname ? realname : "<DEFAULT>"; ECPGlog("connect: could not open database %s on %s port %s %s%s%s%s in line %d\n\t%s\n", db, host ? host : "<DEFAULT>", port ? port : "<DEFAULT>", options ? "with options " : "", options ? options : "", user ? "for user " : "", user ? user : "", lineno, errmsg); ecpg_finish(this); #ifdef ENABLE_THREAD_SAFETY pthread_mutex_unlock(&connections_mutex); #endif ECPGraise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db); if (host) ECPGfree(host); if (port) ECPGfree(port); if (options) ECPGfree(options); if (realname) ECPGfree(realname); if (dbname) ECPGfree(dbname); return false; } #ifdef ENABLE_THREAD_SAFETY pthread_mutex_unlock(&connections_mutex); #endif if (host) ECPGfree(host); if (port) ECPGfree(port); if (options) ECPGfree(options); if (realname) ECPGfree(realname); if (dbname) ECPGfree(dbname); this->committed = true; this->autocommit = autocommit; PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, (void *) this); return true; }