int fb_error(rlm_sql_firebird_conn_t *conn) { ISC_SCHAR error[2048]; /* Only 1024 bytes should be written to this, but were playing it extra safe */ ISC_STATUS *pstatus; conn->sql_code = 0; /* * Free any previous errors. */ TALLOC_FREE(conn->error); /* * Check if the status array contains an error */ if (IS_ISC_ERROR(conn->status)) { conn->sql_code = isc_sqlcode(conn->status); /* * pstatus is a pointer into the status array which is * advanced by isc_interprete. It's initialised to the * first element of the status array. */ pstatus = &conn->status[0]; /* * It's deprecated because the size of the buffer isn't * passed and this isn't safe. But as were passing a very * large buffer it's unlikely this will be an issue, and * allows us to maintain compatibility with the interbase * API. */ isc_interprete(&error[0], &pstatus); conn->error = talloc_typed_asprintf(conn, "%s. ", &error[0]); while (isc_interprete(&error[0], &pstatus)) { conn->error = talloc_asprintf_append(conn->error, "%s. ", &error[0]); } memset(&conn->status, 0, sizeof(conn->status)); } return conn->sql_code; }
EXPORT RM_ENTRY(rmc_interprete) { ClearParamPool(); char *bfr = (char *)AllocStringPool(arg_vector[0].a_length + 1); ISC_STATUS retval = isc_interprete(bfr, (ISC_STATUS **)arg_vector[1].a_address); StringToCobol(&arg_vector[0], (ISC_UCHAR *)bfr); IntToCobol(&arg_vector[-1], (ISC_UINT64)retval); return (0); }
/* print interbase error and save it for ibase_errmsg() */ void _php_ibase_error(TSRMLS_D) /* {{{ */ { char *s = IBG(errmsg); ISC_STATUS *statusp = IB_STATUS; IBG(sql_code) = isc_sqlcode(IB_STATUS); while ((s - IBG(errmsg)) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && isc_interprete(s, &statusp)) { strcat(IBG(errmsg), " "); s = IBG(errmsg) + strlen(IBG(errmsg)); } php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", IBG(errmsg)); }
int _dbd_real_connect(dbi_conn_t *conn, char *enc) { char dpb_buffer[256], *dpb, *p, *fb_encoding; char dbase[256]; short dpb_length; char db_fullpath[PATH_MAX]; isc_db_handle db = 0L; /* database handle */ isc_tr_handle trans = 0L; /* transaction handle */ ibase_conn_t *iconn = (ibase_conn_t * ) malloc(sizeof(ibase_conn_t)); ISC_STATUS status_vector[ISC_STATUS_LENGTH]; const char *dbname = dbi_conn_get_option(conn, "dbname"); const char *host = dbi_conn_get_option(conn, "host"); const char *username = dbi_conn_get_option(conn, "username"); const char *password = dbi_conn_get_option(conn, "password"); const char *encoding = dbi_conn_get_option(conn, "encoding"); if(encoding == NULL || *encoding == '\0') encoding = "NONE"; dpb = dpb_buffer; *dpb++ = isc_dpb_version1; *dpb++ = isc_dpb_num_buffers; *dpb++ = 1; *dpb++ = 90; *dpb++ = isc_dpb_user_name; *dpb++ = strlen(username); for (p = (char*)username; *p; *dpb++ = *p++); *dpb++ = isc_dpb_password; *dpb++ = strlen(password); for (p = (char*)password; *p; *dpb++ = *p++); *dpb++ = isc_dpb_lc_ctype; fb_encoding = (char*)dbd_encoding_from_iana(encoding); *dpb++ = strlen(fb_encoding); for (p = fb_encoding; *p; *dpb++ = *p++); dpb_length = dpb - dpb_buffer; dpb = dpb_buffer; /* could be used here, but is tagged deprecated */ /* isc_expand_dpb(&dpb, &dpb_length, */ /* isc_dpb_user_name, username, */ /* isc_dpb_password, password, */ /* isc_dpb_lc_ctype, dbd_encoding_from_iana(encoding), */ /* NULL); */ if (!dbname) { _dbd_internal_error_handler(conn, "no database specified", DBI_ERROR_DBD); return -1; } _firebird_populate_db_string( conn, dbname, db_fullpath ); if (host == NULL || !*host) { snprintf(dbase, 256, "%s", db_fullpath); } else { snprintf(dbase, 256, "%s:%s", host, db_fullpath); } /* printf("dbase went to: %s<<; host: %s, username: %s, passwd: %s, encoding: %s; dbp:%s<<\n", dbase, host, username, password, encoding, dpb); */ /* fflush(stdout); */ isc_attach_database(status_vector, strlen(dbase), dbase, &db, dpb_length, dpb); if (status_vector[0] == 1 && status_vector[1]) { char msg[512]; long* pvector = status_vector; dealocate_iconn( iconn ); isc_interprete(msg, &pvector); _dbd_internal_error_handler(conn, msg, DBI_ERROR_DBD); return -1; } else { isc_start_transaction(status_vector, &trans, 1, &db, 0, NULL); } iconn->trans = trans; iconn->db = db; iconn->charset = strdup(encoding); conn->connection = (void *)iconn; if (dbase) conn->current_db = strdup(dbase); return 0; }
static int perform_ibase_search(uschar * query, uschar * server, uschar ** resultptr, uschar ** errmsg, BOOL * defer_break) { isc_stmt_handle stmth = NULL; XSQLDA *out_sqlda; XSQLVAR *var; char buffer[256]; ISC_STATUS status[20], *statusp = status; int i; int ssize = 0; int offset = 0; int yield = DEFER; uschar *result = NULL; ibase_connection *cn; uschar *server_copy = NULL; uschar *sdata[3]; /* Disaggregate the parameters from the server argument. The order is host, database, user, password. We can write to the string, since it is in a nextinlist temporary buffer. The copy of the string that is used for caching has the password removed. This copy is also used for debugging output. */ for (i = 2; i > 0; i--) { uschar *pp = Ustrrchr(server, '|'); if (pp == NULL) { *errmsg = string_sprintf("incomplete Interbase server data: %s", (i == 3) ? server : server_copy); *defer_break = TRUE; return DEFER; } *pp++ = 0; sdata[i] = pp; if (i == 2) server_copy = string_copy(server); /* sans password */ } sdata[0] = server; /* What's left at the start */ /* See if we have a cached connection to the server */ for (cn = ibase_connections; cn != NULL; cn = cn->next) { if (Ustrcmp(cn->server, server_copy) == 0) { break; } } /* Use a previously cached connection ? */ if (cn != NULL) { static char db_info_options[] = { isc_info_base_level }; /* test if the connection is alive */ if (isc_database_info (status, &cn->dbh, sizeof(db_info_options), db_info_options, sizeof(buffer), buffer)) { /* error occurred: assume connection is down */ DEBUG(D_lookup) debug_printf ("Interbase cleaning up cached connection: %s\n", cn->server); isc_detach_database(status, &cn->dbh); } else { DEBUG(D_lookup) debug_printf("Interbase using cached connection for %s\n", server_copy); } } else { cn = store_get(sizeof(ibase_connection)); cn->server = server_copy; cn->dbh = NULL; cn->transh = NULL; cn->next = ibase_connections; ibase_connections = cn; } /* If no cached connection, we must set one up. */ if (cn->dbh == NULL || cn->transh == NULL) { char *dpb, *p; short dpb_length; static char trans_options[] = { isc_tpb_version3, isc_tpb_read, isc_tpb_read_committed, isc_tpb_rec_version }; /* Construct the database parameter buffer. */ dpb = buffer; *dpb++ = isc_dpb_version1; *dpb++ = isc_dpb_user_name; *dpb++ = strlen(sdata[1]); for (p = sdata[1]; *p;) *dpb++ = *p++; *dpb++ = isc_dpb_password; *dpb++ = strlen(sdata[2]); for (p = sdata[2]; *p;) *dpb++ = *p++; dpb_length = dpb - buffer; DEBUG(D_lookup) debug_printf("new Interbase connection: database=%s user=%s\n", sdata[0], sdata[1]); /* Connect to the database */ if (isc_attach_database (status, 0, sdata[0], &cn->dbh, dpb_length, buffer)) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase attach() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } /* Now start a read-only read-committed transaction */ if (isc_start_transaction (status, &cn->transh, 1, &cn->dbh, sizeof(trans_options), trans_options)) { isc_interprete(buffer, &statusp); isc_detach_database(status, &cn->dbh); *errmsg = string_sprintf("Interbase start_transaction() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } } /* Run the query */ if (isc_dsql_allocate_statement(status, &cn->dbh, &stmth)) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase alloc_statement() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } out_sqlda = store_get(XSQLDA_LENGTH(1)); out_sqlda->version = SQLDA_VERSION1; out_sqlda->sqln = 1; if (isc_dsql_prepare (status, &cn->transh, &stmth, 0, query, 1, out_sqlda)) { isc_interprete(buffer, &statusp); store_reset(out_sqlda); out_sqlda = NULL; *errmsg = string_sprintf("Interbase prepare_statement() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } /* re-allocate the output structure if there's more than one field */ if (out_sqlda->sqln < out_sqlda->sqld) { XSQLDA *new_sqlda = store_get(XSQLDA_LENGTH(out_sqlda->sqld)); if (isc_dsql_describe (status, &stmth, out_sqlda->version, new_sqlda)) { isc_interprete(buffer, &statusp); isc_dsql_free_statement(status, &stmth, DSQL_drop); store_reset(out_sqlda); out_sqlda = NULL; *errmsg = string_sprintf("Interbase describe_statement() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } out_sqlda = new_sqlda; } /* allocate storage for every returned field */ for (i = 0, var = out_sqlda->sqlvar; i < out_sqlda->sqld; i++, var++) { switch (var->sqltype & ~1) { case SQL_VARYING: var->sqldata = (char *) store_get(sizeof(char) * var->sqllen + 2); break; case SQL_TEXT: var->sqldata = (char *) store_get(sizeof(char) * var->sqllen); break; case SQL_SHORT: var->sqldata = (char *) store_get(sizeof(short)); break; case SQL_LONG: var->sqldata = (char *) store_get(sizeof(ISC_LONG)); break; #ifdef SQL_INT64 case SQL_INT64: var->sqldata = (char *) store_get(sizeof(ISC_INT64)); break; #endif case SQL_FLOAT: var->sqldata = (char *) store_get(sizeof(float)); break; case SQL_DOUBLE: var->sqldata = (char *) store_get(sizeof(double)); break; #ifdef SQL_TIMESTAMP case SQL_DATE: var->sqldata = (char *) store_get(sizeof(ISC_QUAD)); break; #else case SQL_TIMESTAMP: var->sqldata = (char *) store_get(sizeof(ISC_TIMESTAMP)); break; case SQL_TYPE_DATE: var->sqldata = (char *) store_get(sizeof(ISC_DATE)); break; case SQL_TYPE_TIME: var->sqldata = (char *) store_get(sizeof(ISC_TIME)); break; #endif } if (var->sqltype & 1) { var->sqlind = (short *) store_get(sizeof(short)); } } /* finally, we're ready to execute the statement */ if (isc_dsql_execute (status, &cn->transh, &stmth, out_sqlda->version, NULL)) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase describe_statement() failed: %s", buffer); isc_dsql_free_statement(status, &stmth, DSQL_drop); *defer_break = FALSE; goto IBASE_EXIT; } while (isc_dsql_fetch(status, &stmth, out_sqlda->version, out_sqlda) != 100L) { /* check if an error occurred */ if (status[0] & status[1]) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase fetch() failed: %s", buffer); isc_dsql_free_statement(status, &stmth, DSQL_drop); *defer_break = FALSE; goto IBASE_EXIT; } if (result != NULL) result = string_catn(result, &ssize, &offset, US "\n", 1); /* Find the number of fields returned. If this is one, we don't add field names to the data. Otherwise we do. */ if (out_sqlda->sqld == 1) { if (out_sqlda->sqlvar[0].sqlind == NULL || *out_sqlda->sqlvar[0].sqlind != -1) /* NULL value yields nothing */ result = string_catn(result, &ssize, &offset, US buffer, fetch_field(buffer, sizeof(buffer), &out_sqlda->sqlvar[0])); } else for (i = 0; i < out_sqlda->sqld; i++) { int len = fetch_field(buffer, sizeof(buffer), &out_sqlda->sqlvar[i]); result = string_cat(result, &ssize, &offset, US out_sqlda->sqlvar[i].aliasname, out_sqlda->sqlvar[i].aliasname_length); result = string_catn(result, &ssize, &offset, US "=", 1); /* Quote the value if it contains spaces or is empty */ if (*out_sqlda->sqlvar[i].sqlind == -1) { /* NULL value */ result = string_catn(result, &ssize, &offset, US "\"\"", 2); } else if (buffer[0] == 0 || Ustrchr(buffer, ' ') != NULL) { int j; result = string_catn(result, &ssize, &offset, US "\"", 1); for (j = 0; j < len; j++) { if (buffer[j] == '\"' || buffer[j] == '\\') result = string_cat(result, &ssize, &offset, US "\\", 1); result = string_cat(result, &ssize, &offset, US buffer + j, 1); } result = string_catn(result, &ssize, &offset, US "\"", 1); } else { result = string_catn(result, &ssize, &offset, US buffer, len); } result = string_catn(result, &ssize, &offset, US " ", 1); } } /* If result is NULL then no data has been found and so we return FAIL. Otherwise, we must terminate the string which has been built; string_cat() always leaves enough room for a terminating zero. */ if (result == NULL) { yield = FAIL; *errmsg = US "Interbase: no data found"; } else { result[offset] = 0; store_reset(result + offset + 1); } /* Get here by goto from various error checks. */ IBASE_EXIT: if (stmth != NULL) isc_dsql_free_statement(status, &stmth, DSQL_drop); /* Non-NULL result indicates a successful result */ if (result != NULL) { *resultptr = result; return OK; } else { DEBUG(D_lookup) debug_printf("%s\n", *errmsg); return yield; /* FAIL or DEFER */ } }