From: Arran Cudbard-Bell Date: Sat, 2 Mar 2013 21:41:31 +0000 (-0500) Subject: Reformatting in firebird X-Git-Tag: debian/3.0.0git+dfsg+moonshot3-2~28 X-Git-Url: http://www.project-moonshot.org/gitweb/?a=commitdiff_plain;ds=sidebyside;h=c16e6e4fae804813fbbc5cd317f76daa21340c10;p=freeradius.git Reformatting in firebird --- diff --git a/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c b/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c index 935a2e6..32ed1a3 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c @@ -32,265 +32,243 @@ static int sql_affected_rows(rlm_sql_handle_t *handle, rlm_sql_config_t *config) static int sql_num_fields(rlm_sql_handle_t *handle, rlm_sql_config_t *config); static int sql_finish_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config); -/************************************************************************* +/** Establish connection to the db * - * Function: sql_init_socket - * - * Purpose: Establish connection to the db - * - *************************************************************************/ + */ static int sql_init_socket(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { - rlm_sql_firebird_sock *firebird_sock; - long res; - - - if (!handle->conn) { - handle->conn = (rlm_sql_firebird_sock *)rad_malloc(sizeof(rlm_sql_firebird_sock)); - if (!handle->conn) return -1; - } - - firebird_sock = handle->conn; - - res=fb_init_socket(firebird_sock); - if (res) return -1; - - if (fb_connect(firebird_sock,config)) { - radlog(L_ERR, "rlm_sql_firebird: Connection failed %s\n", firebird_sock->lasterror); - return SQL_DOWN; - } - - return 0; + rlm_sql_firebird_sock *firebird_sock; + + long res; + + if (!handle->conn) { + handle->conn = rad_malloc(sizeof(rlm_sql_firebird_sock)); + if (!handle->conn) { + return -1; + } + } + + firebird_sock = handle->conn; + + res = fb_init_socket(firebird_sock); + if (res) { + return -1; + } + + if (fb_connect(firebird_sock,config)) { + radlog(L_ERR, "rlm_sql_firebird: Connection failed %s\n", + firebird_sock->lasterror); + + return SQL_DOWN; + } + + return 0; } - -/************************************************************************* - * - * Function: sql_destroy_socket - * - * Purpose: Free socket and private connection data +/** Free socket and private connection data * - *************************************************************************/ -static int sql_destroy_socket(rlm_sql_handle_t *handle, rlm_sql_config_t *config) + */ +static int sql_destroy_socket(rlm_sql_handle_t *handle, + rlm_sql_config_t *config) { - free(handle->conn); - handle->conn = NULL; - return 0; + free(handle->conn); + + handle->conn = NULL; + + return 0; } -/************************************************************************* - * - * Function: sql_query +/** Issue a non-SELECT query (ie: update/delete/insert) to the database. * - * Purpose: Issue a non-SELECT query (ie: update/delete/insert) to - * the database. - * - *************************************************************************/ - -static int sql_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char *querystr) { - rlm_sql_firebird_sock *firebird_sock = handle->conn; - int deadlock=0; + */ +static int sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config, + char *querystr) { + rlm_sql_firebird_sock *firebird_sock = handle->conn; + + int deadlock = 0; #ifdef _PTHREAD_H - pthread_mutex_lock(&firebird_sock->mut); + pthread_mutex_lock(&firebird_sock->mut); #endif -TryAgain: - if (fb_sql_query(firebird_sock,querystr)) { -//Try again query when deadlock, beacuse in any case it will be retried. -// but may be lost for short sessions - if ((firebird_sock->sql_code==DEADLOCK_SQL_CODE) && !deadlock) { - radlog(L_DBG,"sock_id deadlock. Retry query %s\n",querystr); -//For non READ_COMMITED transactions put rollback here -// fb_rollback(sock); - deadlock=1; - goto TryAgain; - } - radlog(L_ERR, "sock_id rlm_sql_firebird,sql_query error:sql_code=%li, error='%s', query=%s\n", - firebird_sock->sql_code, - firebird_sock->lasterror, - querystr); - - if ((firebird_sock->sql_code==DOWN_SQL_CODE)) return SQL_DOWN; -//free problem query - if (fb_rollback(firebird_sock)) { - //assume the network is down if rollback had failed - radlog(L_ERR,"Fail to rollback transaction after previous error. Error: %s\n", - firebird_sock->lasterror); - return SQL_DOWN; - } -// firebird_sock->in_use=0; - return -1; - } - - if (firebird_sock->statement_type!=isc_info_sql_stmt_select) { - if (fb_commit(firebird_sock)) return -1; - } - - return 0; + try_again: + /* + * Try again query when deadlock, beacuse in any case it + * will be retried. + */ + if (fb_sql_query(firebird_sock,querystr)) { + /* but may be lost for short sessions */ + if ((firebird_sock->sql_code == DEADLOCK_SQL_CODE) && + !deadlock) { + radlog(L_DBG,"sock_id deadlock. Retry query %s", + querystr); + + /* + * @todo For non READ_COMMITED transactions put + * rollback here + * fb_rollback(sock); + */ + deadlock = 1; + goto try_again; + } + + radlog(L_ERR, "sock_id rlm_sql_firebird,sql_query error: " + "sql_code=%li, error='%s', query=%s", + (long int) firebird_sock->sql_code, + firebird_sock->lasterror, + querystr); + + if (firebird_sock->sql_code == DOWN_SQL_CODE) { + return SQL_DOWN; + } + + /* Free problem query */ + if (fb_rollback(firebird_sock)) { + //assume the network is down if rollback had failed + radlog(L_ERR,"Fail to rollback transaction after " + "previous error. Error: %s", + firebird_sock->lasterror); + + return SQL_DOWN; + } + // firebird_sock->in_use=0; + return -1; + } + + if (firebird_sock->statement_type != isc_info_sql_stmt_select) { + if (fb_commit(firebird_sock)) { + return -1; + } + } + + return 0; } - -/************************************************************************* - * - * Function: sql_select_query +/** Issue a select query to the database. * - * Purpose: Issue a select query to the database - * - *************************************************************************/ -static int sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char *querystr) { -// rlm_sql_firebird_sock *firebird_sock = handle->conn; - return (sql_query(handle, config, querystr)); - + */ +static int sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config, + char *querystr) { + return sql_query(handle, config, querystr); } - -/************************************************************************* - * - * Function: sql_store_result - * - * Purpose: database specific store_result function. Returns a result - * set for the query. +/** Returns a result set for the query. * - *************************************************************************/ -static int sql_store_result(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { - /* Not used */ - return 0; + */ +static int sql_store_result(UNUSED rlm_sql_handle_t *handle, + UNUSED rlm_sql_config_t *config) { + return 0; } - -/************************************************************************* - * - * Function: sql_num_fields - * - * Purpose: database specific num_fields function. Returns number - * of columns from query +/** Returns number of columns from query. * - *************************************************************************/ -static int sql_num_fields(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { - return ((rlm_sql_firebird_sock *) handle->conn)->sqlda_out->sqld; + */ +static int sql_num_fields(rlm_sql_handle_t *handle, + UNUSED rlm_sql_config_t *config) { + return ((rlm_sql_firebird_sock *) handle->conn)->sqlda_out->sqld; } - -/************************************************************************* - * - * Function: sql_num_rows - * - * Purpose: database specific num_rows. Returns number of rows in - * query +/** Returns number of rows in query. * - *************************************************************************/ + */ static int sql_num_rows(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { - int res=sql_affected_rows(handle, config); - return res; + return sql_affected_rows(handle, config); } - -/************************************************************************* - * - * Function: sql_fetch_row - * - * Purpose: database specific fetch_row. Returns a rlm_sql_row_t struct - * with all the data for the query in 'handle->row'. Returns - * 0 on success, -1 on failure, SQL_DOWN if 'database is down'. +/** Returns an individual row. * - *************************************************************************/ + */ static int sql_fetch_row(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { - rlm_sql_firebird_sock *firebird_sock = handle->conn; - int res; - - handle->row = NULL; - if (firebird_sock->statement_type!=isc_info_sql_stmt_exec_procedure) { - res=fb_fetch(firebird_sock); - if (res==100) return 0; - if (res) { - radlog(L_ERR, "rlm_sql_firebird. Fetch problem:'%s'\n", firebird_sock->lasterror); - return -1; - } - } else firebird_sock->statement_type=0; - fb_store_row(firebird_sock); - - handle->row = firebird_sock->row; - return 0; + rlm_sql_firebird_sock *firebird_sock = handle->conn; + int res; + + handle->row = NULL; + + if (firebird_sock->statement_type != isc_info_sql_stmt_exec_procedure) { + res = fb_fetch(firebird_sock); + if (res == 100) { + return 0; + } + + if (res) { + radlog(L_ERR, "rlm_sql_firebird. Fetch problem:'%s'", + firebird_sock->lasterror); + + return -1; + } + } else { + firebird_sock->statement_type=0; + } + + fb_store_row(firebird_sock); + + handle->row = firebird_sock->row; + + return 0; } - -/************************************************************************* +/** End the select query, such as freeing memory or result. * - * Function: sql_finish_select_query - * - * Purpose: End the select query, such as freeing memory or result - * - *************************************************************************/ -static int sql_finish_select_query(rlm_sql_handle_t * handle, rlm_sql_config_t *config) { - rlm_sql_firebird_sock *sock=(rlm_sql_firebird_sock *) handle->conn; - fb_commit(sock); - fb_close_cursor(sock); - return 0; + */ +static int sql_finish_select_query(rlm_sql_handle_t *handle, + UNUSED rlm_sql_config_t *config) { + + rlm_sql_firebird_sock *sock = (rlm_sql_firebird_sock *) handle->conn; + + fb_commit(sock); + fb_close_cursor(sock); + + return 0; } -/************************************************************************* - * - * Function: sql_finish_query +/** End the query * - * Purpose: End the query, such as freeing memory - * - *************************************************************************/ -static int sql_finish_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { -// sql_free_result(handle,config); - return 0; + */ +static int sql_finish_query(rlm_sql_handle_t *handle, + rlm_sql_config_t *config) { + sql_free_result(handle, config); + + return 0; } -/************************************************************************* - * - * Function: sql_free_result - * - * Purpose: database specific free_result. Frees memory allocated - * for a result set +/** Frees memory allocated for a result set. * - *************************************************************************/ -static int sql_free_result(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { - return 0; + */ +static int sql_free_result(UNUSED rlm_sql_handle_t *handle, + UNUSED rlm_sql_config_t *config) { + return 0; } -/************************************************************************* - * - * Function: sql_close +/** Closes an open database connection and cleans up any open handles. * - * Purpose: database specific close. Closes an open database - * connection and cleans up any open handles. - * - *************************************************************************/ + */ static int sql_close(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { - fb_destroy_socket((rlm_sql_firebird_sock *) handle->conn); - return 0; + fb_destroy_socket((rlm_sql_firebird_sock *) handle->conn); + return 0; } -/************************************************************************* +/** Returns error associated with connection. * - * Function: sql_error - * - * Purpose: database specific error. Returns error associated with - * connection - * - *************************************************************************/ -static const char *sql_error(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { - rlm_sql_firebird_sock *firebird_sock = handle->conn; - return firebird_sock->lasterror; + */ +static const char *sql_error(rlm_sql_handle_t *handle, + UNUSED rlm_sql_config_t *config) { + rlm_sql_firebird_sock *firebird_sock = handle->conn; + + return firebird_sock->lasterror; } -/************************************************************************* - * - * Function: sql_affected_rows - * - * Purpose: Return the number of rows affected by the query (update, - * or insert) + +/** Return the number of rows affected by the query (update, or insert) * - *************************************************************************/ + */ static int sql_affected_rows(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { - int affected_rows=fb_affected_rows(handle->conn); - if (affected_rows<0) - radlog(L_ERR, "sql_affected_rows, rlm_sql_firebird. error:%s\n", sql_error(handle,config)); - return affected_rows; + int affected_rows=fb_affected_rows(handle->conn); + + if (affected_rows < 0) { + radlog(L_ERR, "sql_affected_rows, rlm_sql_firebird. error:%s\n", + sql_error(handle,config)); + } + + return affected_rows; } /* Exported to rlm_sql */ diff --git a/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.c b/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.c index bf85808..39a9896 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.c @@ -27,81 +27,110 @@ RCSID("$Id$") #include int fb_lasterror(rlm_sql_firebird_sock *sock) { - char msg[512+2]; - int l; - ISC_LONG *pstatus; - char *p=0; - - sock->sql_code=0; - - if (IS_ISC_ERROR(sock->status)) { -//if error occured, free the previous error's text and create a new one - pstatus=sock->status; - if (sock->lasterror) free(sock->lasterror); - sock->lasterror=0; - sock->sql_code=isc_sqlcode(sock->status); - isc_interprete(msg,&pstatus); - p=strdup(msg); - msg[0]='.';msg[1]=' '; - while (isc_interprete(msg+2,&pstatus)) { - l=strlen(p); - p=(char *) realloc(p,l+strlen(msg)+2); - strcat(p,msg); - } - sock->lasterror=p; - } else { -//return empty (but not null) string if there are no error - if (sock->lasterror) *sock->lasterror=0; - else sock->lasterror=strdup(""); - } - return sock->sql_code; + char msg[512+2]; + int l; + ISC_LONG *pstatus; + char *p = 0; + + sock->sql_code = 0; + + if (IS_ISC_ERROR(sock->status)) { + /* + * If error occured, free the previous error's text + * and create a new one. + */ + pstatus = sock->status; + if (sock->lasterror) { + free(sock->lasterror); + } + + sock->lasterror = 0; + sock->sql_code = isc_sqlcode(sock->status); + + isc_interprete(msg,&pstatus); + p = strdup(msg); + + msg[0] = '.'; + msg[1] = ' '; + + while (isc_interprete(msg + 2, &pstatus)) { + l = strlen(p); + p = realloc(p, l + strlen(msg) + 2); + + strcat(p, msg); + } + + sock->lasterror=p; + } else { + //return empty (but not null) string if there are no error + if (sock->lasterror) { + *(sock->lasterror) = '\0'; + } else { + sock->lasterror = strdup(""); + } + } + + return sock->sql_code; } -void fb_set_tpb(rlm_sql_firebird_sock * sock, int count,...) { - int i; - va_list arg; - va_start(arg,count); - sock->tpb=(char *) malloc(count); - for (i=0; itpb[i]=(char ) va_arg(arg,int); - } - sock->tpb_len=count; +void fb_set_tpb(rlm_sql_firebird_sock * sock, int count, ...) { + int i; + va_list arg; + + va_start(arg, count); + sock->tpb = malloc(count); + + for (i = 0; i < count; i++) { + sock->tpb[i] = (char) va_arg(arg, int); + } + + sock->tpb_len=count; } void fb_dpb_add_str(char **dpb, char name, char *value) { - int l; - if (!value) return; - l=strlen(value); - - *(*dpb)++ = name; - *(*dpb)++ = (char ) l; - memmove(*dpb,value,l); - *dpb+=l; - + int l; + + if (!value) { + return; + } + + l = strlen(value); + + *(*dpb)++ = name; + *(*dpb)++ = (char) l; + + memmove(*dpb, value, l); + + *dpb += l; } void fb_free_sqlda(XSQLDA *sqlda) { - int i; - for (i=0; isqld; i++) { - free(sqlda->sqlvar[i].sqldata); - free(sqlda->sqlvar[i].sqlind); - } - sqlda->sqld=0; + int i; + for (i = 0; i < sqlda->sqld; i++) { + free(sqlda->sqlvar[i].sqldata); + free(sqlda->sqlvar[i].sqlind); + } + sqlda->sqld = 0; } void fb_set_sqlda(XSQLDA *sqlda) { - int i; - for (i=0; isqld; i++) { - if ((sqlda->sqlvar[i].sqltype & ~1)==SQL_VARYING) - sqlda->sqlvar[i].sqldata = (char*)malloc(sqlda->sqlvar[i].sqllen + sizeof(short)); - else - sqlda->sqlvar[i].sqldata = (char*)malloc(sqlda->sqlvar[i].sqllen); - - if (sqlda->sqlvar[i].sqltype & 1) sqlda->sqlvar[i].sqlind = (short*)calloc(sizeof(short),1); - else sqlda->sqlvar[i].sqlind = 0; - } + int i; + + for (i = 0; i < sqlda->sqld; i++) { + if ((sqlda->sqlvar[i].sqltype & ~1) == SQL_VARYING) { + sqlda->sqlvar[i].sqldata = (char*)malloc(sqlda->sqlvar[i].sqllen + sizeof(short)); + } else { + sqlda->sqlvar[i].sqldata = (char*)malloc(sqlda->sqlvar[i].sqllen); + } + + if (sqlda->sqlvar[i].sqltype & 1) { + sqlda->sqlvar[i].sqlind = (short*)calloc(sizeof(short),1); + } else { + sqlda->sqlvar[i].sqlind = 0; + } + } } @@ -110,395 +139,469 @@ void fb_set_sqlda(XSQLDA *sqlda) { //Structure to manage a SQL_VARYING Firebird's data types typedef struct vary_fb { - short vary_length; - char vary_string[1]; + short vary_length; + char vary_string[1]; } VARY; //function fb_store_row based on fiebird's apifull example void fb_store_row(rlm_sql_firebird_sock *sock) { - int dtype; - struct tm times; - ISC_QUAD bid; - int i; - XSQLVAR *var; - VARY * vary; - -//assumed: id,username,attribute,value,op - if (sock->row_fcountsqlda_out->sqld) { - i=sock->row_fcount; - sock->row_fcount=sock->sqlda_out->sqld; - sock->row=(char **) realloc(sock->row,sock->row_fcount*sizeof(char *)); - sock->row_sizes=(int *) realloc(sock->row_sizes,sock->row_fcount*sizeof(int)); - while(irow_fcount) { - sock->row[i]=0; - sock->row_sizes[i++]=0; - } - } - -for (i=0, var=sock->sqlda_out->sqlvar; isqlda_out->sqld; var++,i++) { -//Initial buffer size to store field's data is 256 bytes - if (sock->row_sizes[i]<256) { - sock->row[i]=(char *) realloc(sock->row[i],256); - sock->row_sizes[i]=256; - } - - if (IS_NULL(var)) { - strcpy(sock->row[i],"NULL"); - continue; - } - dtype=var->sqltype & ~1; - switch (dtype) { - case SQL_TEXT: - if (sock->row_sizes[i]<=var->sqllen) { - sock->row_sizes[i]=var->sqllen+1; - sock->row[i]=(char *) realloc(sock->row[i],sock->row_sizes[i]); - } - memmove(sock->row[i],var->sqldata,var->sqllen); - sock->row[i][var->sqllen]=0; - break; - case SQL_VARYING: - vary = (VARY*) var->sqldata; - if (sock->row_sizes[i]<=vary->vary_length) { - sock->row_sizes[i]=vary->vary_length+1; - sock->row[i]=(char *) realloc(sock->row[i],sock->row_sizes[i]); - } - memmove(sock->row[i],vary->vary_string,vary->vary_length); - sock->row[i][vary->vary_length] =0; - break; - - case SQL_FLOAT: - snprintf(sock->row[i],sock->row_sizes[i], "%15g", *(float ISC_FAR *) (var->sqldata)); - break; - case SQL_SHORT: - case SQL_LONG: - case SQL_INT64: - { - ISC_INT64 value = 0; - short field_width = 0; - short dscale = 0; - char *p; - p=sock->row[i]; - switch (dtype) - { - case SQL_SHORT: - value = (ISC_INT64) *(short *) var->sqldata; - field_width = 6; + int dtype; + struct tm times; + ISC_QUAD bid; + int i; + XSQLVAR *var; + VARY * vary; + + /* assumed: id,username,attribute,value,op */ + if (sock->row_fcountsqlda_out->sqld) { + i=sock->row_fcount; + sock->row_fcount=sock->sqlda_out->sqld; + sock->row = (char **) realloc(sock->row, sock->row_fcount * sizeof(char *)); + sock->row_sizes = (int *) realloc(sock->row_sizes, sock->row_fcount * sizeof(int)); + + while( i row_fcount) { + sock->row[i] = 0; + sock->row_sizes[i++] = 0; + } + } + + for (i=0, var=sock->sqlda_out->sqlvar; isqlda_out->sqld; var++,i++) { + /* + * Initial buffer size to store field's data is 256 bytes + */ + if (sock->row_sizes[i]<256) { + sock->row[i]=(char *) realloc(sock->row[i],256); + sock->row_sizes[i]=256; + } + + if (IS_NULL(var)) { + strcpy(sock->row[i],"NULL"); + continue; + } + + dtype = var->sqltype & ~1; + + switch (dtype) { + case SQL_TEXT: + if (sock->row_sizes[i]<=var->sqllen) { + sock->row_sizes[i] = var->sqllen + 1; + sock->row[i] = realloc(sock->row[i], + sock->row_sizes[i]); + } + + memmove(sock->row[i], var->sqldata, var->sqllen); + sock->row[i][var->sqllen] = 0; + break; - case SQL_LONG: - value = (ISC_INT64) *(int *) var->sqldata; - field_width = 11; + case SQL_VARYING: + vary = (VARY*) var->sqldata; + if (sock->row_sizes[i] <= vary->vary_length) { + sock->row_sizes[i] = vary->vary_length+1; + sock->row[i] = realloc(sock->row[i], + sock->row_sizes[i]); + } + memmove(sock->row[i],vary->vary_string,vary->vary_length); + sock->row[i][vary->vary_length] = 0; + break; - case SQL_INT64: - value = (ISC_INT64) *(ISC_INT64 *) var->sqldata; - field_width = 21; + + case SQL_FLOAT: + snprintf(sock->row[i], sock->row_sizes[i], "%15g", + *(float ISC_FAR *) (var->sqldata)); break; - } - dscale = var->sqlscale; - if (dscale < 0) - { - ISC_INT64 tens; - short j; - - tens = 1; - for (j = 0; j > dscale; j--) tens *= 10; - - if (value >= 0) - sprintf (p, "%*lld.%0*lld", - field_width - 1 + dscale, - (ISC_INT64) value / tens, - -dscale, - (ISC_INT64) value % tens); - else if ((value / tens) != 0) - sprintf (p, "%*lld.%0*lld", - field_width - 1 + dscale, - (ISC_INT64) (value / tens), - -dscale, - (ISC_INT64) -(value % tens)); - else - sprintf (p, "%*s.%0*lld", - field_width - 1 + dscale, - "-0", - -dscale, - (ISC_INT64) -(value % tens)); - } - else if (dscale) - sprintf (p, "%*lld%0*d", - field_width, - (ISC_INT64) value, - dscale, 0); - else - sprintf (p, "%*lld", - field_width, - (ISC_INT64) value); + case SQL_SHORT: + case SQL_LONG: + case SQL_INT64: + { + ISC_INT64 value = 0; + short field_width = 0; + short dscale = 0; + char *p; + p=sock->row[i]; + + switch (dtype) + { + case SQL_SHORT: + value = (ISC_INT64) *(short *)var->sqldata; + field_width = 6; + break; + case SQL_LONG: + value = (ISC_INT64) *(int *)var->sqldata; + field_width = 11; + break; + case SQL_INT64: + value = (ISC_INT64) *(ISC_INT64 *)var->sqldata; + field_width = 21; + break; + } + dscale = var->sqlscale; + + if (dscale < 0) { + ISC_INT64 tens; + short j; + + tens = 1; + for (j = 0; j > dscale; j--) { + tens *= 10; + } + + if (value >= 0) { + sprintf(p, "%*lld.%0*lld", + field_width - 1 + dscale, + (ISC_INT64) value / tens, + -dscale, + (ISC_INT64) value % tens); + } else if ((value / tens) != 0) { + sprintf (p, "%*lld.%0*lld", + field_width - 1 + dscale, + (ISC_INT64) (value / tens), + -dscale, + (ISC_INT64) -(value % tens)); + } else { + sprintf(p, "%*s.%0*lld", field_width - 1 + dscale, + "-0", -dscale, (ISC_INT64) - (value % tens)); + } + } else if (dscale) { + sprintf(p, "%*lld%0*d", field_width, + (ISC_INT64) value, dscale, 0); + } else { + sprintf(p, "%*lld", field_width, + (ISC_INT64) value); + } + } + break; + + case SQL_D_FLOAT: + case SQL_DOUBLE: + snprintf(sock->row[i],sock->row_sizes[i], "%24f", + *(double ISC_FAR *) (var->sqldata)); + break; + + case SQL_TIMESTAMP: + isc_decode_timestamp((ISC_TIMESTAMP ISC_FAR *)var->sqldata, ×); + snprintf(sock->row[i],sock->row_sizes[i],"%04d-%02d-%02d %02d:%02d:%02d.%04d", + times.tm_year + 1900, + times.tm_mon+1, + times.tm_mday, + times.tm_hour, + times.tm_min, + times.tm_sec, + ((ISC_TIMESTAMP *)var->sqldata)->timestamp_time % 10000); + break; + + case SQL_TYPE_DATE: + isc_decode_sql_date((ISC_DATE ISC_FAR *)var->sqldata, ×); + snprintf(sock->row[i],sock->row_sizes[i], "%04d-%02d-%02d", + times.tm_year + 1900, + times.tm_mon+1, + times.tm_mday); + break; + + case SQL_TYPE_TIME: + isc_decode_sql_time((ISC_TIME ISC_FAR *)var->sqldata, ×); + snprintf(sock->row[i],sock->row_sizes[i], "%02d:%02d:%02d.%04d", + times.tm_hour, + times.tm_min, + times.tm_sec, + (*((ISC_TIME *)var->sqldata)) % 10000); + break; + + case SQL_BLOB: + case SQL_ARRAY: + /* Print the blob id on blobs or arrays */ + bid = *(ISC_QUAD ISC_FAR *) var->sqldata; + snprintf(sock->row[i],sock->row_sizes[i],"%08lx:%08lx", bid.gds_quad_high, bid.gds_quad_low); + break; + } - break; - - - case SQL_DOUBLE: case SQL_D_FLOAT: - snprintf(sock->row[i],sock->row_sizes[i], "%24f", *(double ISC_FAR *) (var->sqldata)); - break; - - case SQL_TIMESTAMP: - isc_decode_timestamp((ISC_TIMESTAMP ISC_FAR *)var->sqldata, ×); - snprintf(sock->row[i],sock->row_sizes[i],"%04d-%02d-%02d %02d:%02d:%02d.%04d", - times.tm_year + 1900, - times.tm_mon+1, - times.tm_mday, - times.tm_hour, - times.tm_min, - times.tm_sec, - ((ISC_TIMESTAMP *)var->sqldata)->timestamp_time % 10000); - break; - - case SQL_TYPE_DATE: - isc_decode_sql_date((ISC_DATE ISC_FAR *)var->sqldata, ×); - snprintf(sock->row[i],sock->row_sizes[i], "%04d-%02d-%02d", - times.tm_year + 1900, - times.tm_mon+1, - times.tm_mday); - break; - - case SQL_TYPE_TIME: - isc_decode_sql_time((ISC_TIME ISC_FAR *)var->sqldata, ×); - snprintf(sock->row[i],sock->row_sizes[i], "%02d:%02d:%02d.%04d", - times.tm_hour, - times.tm_min, - times.tm_sec, - (*((ISC_TIME *)var->sqldata)) % 10000); - break; - - case SQL_BLOB: - case SQL_ARRAY: - /* Print the blob id on blobs or arrays */ - bid = *(ISC_QUAD ISC_FAR *) var->sqldata; - snprintf(sock->row[i],sock->row_sizes[i],"%08lx:%08lx", bid.gds_quad_high, bid.gds_quad_low); - break; - - } //END SWITCH -} //END FOR + } } - -//================= int fb_init_socket(rlm_sql_firebird_sock *sock) { - memset(sock, 0, sizeof(*sock)); - sock->sqlda_out = (XSQLDA ISC_FAR *) calloc(XSQLDA_LENGTH (5),1); - sock->sqlda_out->sqln = 5; - sock->sqlda_out->version = SQLDA_VERSION1; - sock->sql_dialect=3; + memset(sock, 0, sizeof(*sock)); + sock->sqlda_out = (XSQLDA ISC_FAR *) calloc(XSQLDA_LENGTH (5),1); + sock->sqlda_out->sqln = 5; + sock->sqlda_out->version = SQLDA_VERSION1; + sock->sql_dialect = 3; #ifdef _PTHREAD_H - pthread_mutex_init (&sock->mut, NULL); - radlog(L_DBG,"Init mutex %p\n",&sock->mut); + pthread_mutex_init (&sock->mut, NULL); + radlog(L_DBG,"Init mutex %p\n",&sock->mut); #endif - -//set tpb to read_committed/wait/no_rec_version - fb_set_tpb(sock,5, - isc_tpb_version3, - isc_tpb_wait, - isc_tpb_write, - isc_tpb_read_committed, - isc_tpb_no_rec_version); - if (!sock->tpb) return -1; - return 0; + /* + * Set tpb to read_committed/wait/no_rec_version + */ + fb_set_tpb(sock, 5, isc_tpb_version3, isc_tpb_wait, isc_tpb_write, + isc_tpb_read_committed, isc_tpb_no_rec_version); + if (!sock->tpb) { + return -1; + } + + return 0; } int fb_connect(rlm_sql_firebird_sock * sock,rlm_sql_config_t *config) { - char *p; - char * database; - - sock->dpb_len=4; - if (config->sql_login) sock->dpb_len+=strlen(config->sql_login)+2; - if (config->sql_password) sock->dpb_len+=strlen(config->sql_password)+2; - - sock->dpb=(char *) malloc(sock->dpb_len); - p=sock->dpb; - - *sock->dpb++ = isc_dpb_version1; - *sock->dpb++ = isc_dpb_num_buffers; - *sock->dpb++ = 1; - *sock->dpb++ = 90; - - fb_dpb_add_str(&sock->dpb,isc_dpb_user_name,config->sql_login); - fb_dpb_add_str(&sock->dpb,isc_dpb_password,config->sql_password); - - sock->dpb=p; -// Check if database and server in the form of server:database. -// If config->sql_server contains ':', then config->sql_db -// parameter ignored - if (strchr(config->sql_server,':')) database=strdup(config->sql_server); - else { -// Make database and server to be in the form of server:database - int ls=strlen(config->sql_server); - int ld=strlen(config->sql_db); - database=(char *) calloc(ls+ld+2,1); - strcpy(database,config->sql_server); - database[ls]=':'; - memmove(database+ls+1,config->sql_db,ld); - } - isc_attach_database(sock->status, 0, database, &sock->dbh, sock->dpb_len, sock->dpb); - free(database); - return fb_lasterror(sock); + char *p; + char *database; + + sock->dpb_len = 4; + if (config->sql_login) { + sock->dpb_len+=strlen(config->sql_login) + 2; + } + + if (config->sql_password) { + sock->dpb_len += strlen(config->sql_password) + 2; + } + + sock->dpb = (char *) malloc(sock->dpb_len); + p = sock->dpb; + + *sock->dpb++ = isc_dpb_version1; + *sock->dpb++ = isc_dpb_num_buffers; + *sock->dpb++ = 1; + *sock->dpb++ = 90; + + fb_dpb_add_str(&sock->dpb, isc_dpb_user_name, config->sql_login); + fb_dpb_add_str(&sock->dpb, isc_dpb_password, config->sql_password); + + sock->dpb = p; + + /* + * Check if database and server in the form of server:database. + * If config->sql_server contains ':', then config->sql_db + * parameter ignored. + */ + if (strchr(config->sql_server,':')) { + database=strdup(config->sql_server); + } else { + /* + * Make database and server to be in the form + * of server:database + */ + int ls = strlen(config->sql_server); + int ld = strlen(config->sql_db); + database=(char *) calloc(ls+ld+2,1); + strcpy(database,config->sql_server); + database[ls]=':'; + memmove(database+ls+1,config->sql_db,ld); + } + isc_attach_database(sock->status, 0, database, &sock->dbh, + sock->dpb_len, sock->dpb); + free(database); + + return fb_lasterror(sock); } int fb_fetch(rlm_sql_firebird_sock *sock) { - long fetch_stat; - if (sock->statement_type!=isc_info_sql_stmt_select) return 100; - fetch_stat=isc_dsql_fetch(sock->status, &sock->stmt, SQL_DIALECT_V6, sock->sqlda_out); - if (fetch_stat) { - if (fetch_stat!=100L) fb_lasterror(sock); - else sock->sql_code=0; - } - return fetch_stat; + long fetch_stat; + if (sock->statement_type!=isc_info_sql_stmt_select) { + return 100; + } + + fetch_stat = isc_dsql_fetch(sock->status, &sock->stmt, + SQL_DIALECT_V6, sock->sqlda_out); + if (fetch_stat) { + if (fetch_stat!=100L) { + fb_lasterror(sock); + } else { + sock->sql_code=0; + } + } + + return fetch_stat; } int fb_prepare(rlm_sql_firebird_sock *sock,char *sqlstr) { - static char stmt_info[] = { isc_info_sql_stmt_type }; - char info_buffer[128]; - short l; - - if (!sock->trh) { - isc_start_transaction(sock->status,&sock->trh,1,&sock->dbh,sock->tpb_len,sock->tpb); - if (!sock->trh) return -4; - } - - fb_free_statement(sock); - if (!sock->stmt) { - isc_dsql_allocate_statement(sock->status, &sock->dbh, &sock->stmt); - if (!sock->stmt) return -1; - } - - fb_free_sqlda(sock->sqlda_out); - isc_dsql_prepare(sock->status, &sock->trh, &sock->stmt, 0, sqlstr, sock->sql_dialect, sock->sqlda_out); - if (IS_ISC_ERROR(sock->status)) return -2; - - if (sock->sqlda_out->sqlnsqlda_out->sqld) { - sock->sqlda_out->sqln=sock->sqlda_out->sqld; - sock->sqlda_out = (XSQLDA ISC_FAR *) realloc(sock->sqlda_out, XSQLDA_LENGTH (sock->sqlda_out->sqld)); - isc_dsql_describe(sock->status,&sock->stmt,SQL_DIALECT_V6,sock->sqlda_out); - if (IS_ISC_ERROR(sock->status)) return -3; - } - -//get statement type - isc_dsql_sql_info(sock->status, &sock->stmt, sizeof (stmt_info), stmt_info,sizeof (info_buffer), info_buffer); - if (IS_ISC_ERROR(sock->status)) return -4; - - l = (short) isc_vax_integer((char ISC_FAR *) info_buffer + 1, 2); - sock->statement_type = isc_vax_integer((char ISC_FAR *) info_buffer + 3, l); - - if (sock->sqlda_out->sqld) fb_set_sqlda(sock->sqlda_out); //set out sqlda - - return 0; + static char stmt_info[] = { isc_info_sql_stmt_type }; + char info_buffer[128]; + short l; + + if (!sock->trh) { + isc_start_transaction(sock->status, &sock->trh, 1, &sock->dbh, + sock->tpb_len,sock->tpb); + if (!sock->trh) { + return -4; + } + } + + fb_free_statement(sock); + if (!sock->stmt) { + isc_dsql_allocate_statement(sock->status, &sock->dbh, + &sock->stmt); + if (!sock->stmt) { + return -1; + } + } + + fb_free_sqlda(sock->sqlda_out); + isc_dsql_prepare(sock->status, &sock->trh, &sock->stmt, 0, sqlstr, + sock->sql_dialect, sock->sqlda_out); + if (IS_ISC_ERROR(sock->status)) { + return -2; + } + + if (sock->sqlda_out->sqlnsqlda_out->sqld) { + sock->sqlda_out->sqln=sock->sqlda_out->sqld; + sock->sqlda_out = (XSQLDA ISC_FAR *) realloc(sock->sqlda_out, + XSQLDA_LENGTH(sock->sqlda_out->sqld)); + isc_dsql_describe(sock->status, &sock->stmt, SQL_DIALECT_V6, + sock->sqlda_out); + + if (IS_ISC_ERROR(sock->status)) { + return -3; + } + } + /* + * Get statement type + */ + isc_dsql_sql_info(sock->status, &sock->stmt, sizeof(stmt_info), + stmt_info,sizeof(info_buffer), info_buffer); + if (IS_ISC_ERROR(sock->status)) return -4; + + l = (short) isc_vax_integer((char ISC_FAR *) info_buffer + 1, 2); + sock->statement_type = isc_vax_integer((char ISC_FAR *) info_buffer + 3, + l); + + if (sock->sqlda_out->sqld) { + fb_set_sqlda(sock->sqlda_out); //set out sqlda + } + + return 0; } int fb_sql_query(rlm_sql_firebird_sock *sock,char *sqlstr) { - if (fb_prepare(sock,sqlstr)) return fb_lasterror(sock); - switch (sock->statement_type) { - case isc_info_sql_stmt_exec_procedure: - isc_dsql_execute2(sock->status, &sock->trh, &sock->stmt, SQL_DIALECT_V6,0,sock->sqlda_out); - break; - default: - isc_dsql_execute(sock->status, &sock->trh, &sock->stmt, SQL_DIALECT_V6,0); - break; - } - return fb_lasterror(sock); + if (fb_prepare(sock,sqlstr)) { + return fb_lasterror(sock); + } + + switch (sock->statement_type) { + case isc_info_sql_stmt_exec_procedure: + isc_dsql_execute2(sock->status, &sock->trh, &sock->stmt, + SQL_DIALECT_V6, 0, sock->sqlda_out); + break; + default: + isc_dsql_execute(sock->status, &sock->trh, &sock->stmt, + SQL_DIALECT_V6, 0); + break; + } + return fb_lasterror(sock); } int fb_affected_rows(rlm_sql_firebird_sock *sock) { - static char count_info[] = {isc_info_sql_records}; - char info_buffer[128]; - char *p ; - int affected_rows=-1; - - if (!sock->stmt) return -1; - - isc_dsql_sql_info(sock->status, &sock->stmt, - sizeof (count_info), count_info,sizeof (info_buffer), info_buffer); - if (IS_ISC_ERROR(sock->status)) return fb_lasterror(sock); - - p=info_buffer+3; - while (*p != isc_info_end) { - p++; - short len = (short)isc_vax_integer(p,2); - p+=2; - affected_rows = isc_vax_integer(p,len); - if (affected_rows>0) break; - p += len; - } - return affected_rows; + static char count_info[] = {isc_info_sql_records}; + char info_buffer[128]; + char *p ; + int affected_rows = -1; + + if (!sock->stmt) return -1; + + isc_dsql_sql_info(sock->status, &sock->stmt, + sizeof (count_info), count_info, + sizeof (info_buffer), info_buffer); + + if (IS_ISC_ERROR(sock->status)) { + return fb_lasterror(sock); + } + + p = info_buffer + 3; + while (*p != isc_info_end) { + p++; + short len = (short)isc_vax_integer(p, 2); + p += 2; + + affected_rows = isc_vax_integer(p, len); + if (affected_rows > 0) { + break; + } + p += len; + } + return affected_rows; } int fb_close_cursor(rlm_sql_firebird_sock *sock) { - isc_dsql_free_statement(sock->status, &sock->stmt, DSQL_close); - return fb_lasterror(sock); + isc_dsql_free_statement(sock->status, &sock->stmt, DSQL_close); + + return fb_lasterror(sock); } void fb_free_statement(rlm_sql_firebird_sock *sock) { - if (sock->stmt) { - isc_dsql_free_statement(sock->status, &sock->stmt, DSQL_drop); - sock->stmt=0; - } + if (sock->stmt) { + isc_dsql_free_statement(sock->status, &sock->stmt, DSQL_drop); + sock->stmt = 0; + } } int fb_rollback(rlm_sql_firebird_sock *sock) { - sock->sql_code=0; - if (sock->trh) { - isc_rollback_transaction (sock->status,&sock->trh); -// sock->in_use=0; + sock->sql_code = 0; + if (sock->trh) { + isc_rollback_transaction(sock->status, &sock->trh); +// sock->in_use=0; #ifdef _PTHREAD_H - pthread_mutex_unlock(&sock->mut); + pthread_mutex_unlock(&sock->mut); #endif - if (IS_ISC_ERROR(sock->status)) { - return fb_lasterror(sock); - } - } - return sock->sql_code; + if (IS_ISC_ERROR(sock->status)) { + return fb_lasterror(sock); + } + } + return sock->sql_code; } int fb_commit(rlm_sql_firebird_sock *sock) { - sock->sql_code=0; - if (sock->trh) { - isc_commit_transaction (sock->status,&sock->trh); - if (IS_ISC_ERROR(sock->status)) { - fb_lasterror(sock); - radlog(L_ERR,"Fail to commit. Error: %s. Try to rollback.\n",sock->lasterror); - return fb_rollback(sock); - } - } -// sock->in_use=0; + sock->sql_code=0; + if (sock->trh) { + isc_commit_transaction (sock->status,&sock->trh); + if (IS_ISC_ERROR(sock->status)) { + fb_lasterror(sock); + radlog(L_ERR, "Fail to commit. Error: %s. Try to rollback.", + sock->lasterror); + return fb_rollback(sock); + } + } +// sock->in_use=0; #ifdef _PTHREAD_H - pthread_mutex_unlock(&sock->mut); + pthread_mutex_unlock(&sock->mut); #endif - return sock->sql_code; + return sock->sql_code; } int fb_disconnect(rlm_sql_firebird_sock *sock) { - if (sock->dbh) { - fb_free_statement(sock); - isc_detach_database(sock->status,&sock->dbh); - return fb_lasterror(sock); - } - return 0; + if (sock->dbh) { + fb_free_statement(sock); + isc_detach_database(sock->status,&sock->dbh); + return fb_lasterror(sock); + } + return 0; } void fb_destroy_socket(rlm_sql_firebird_sock *sock) { - int i; - fb_commit(sock); - if (fb_disconnect(sock)) { - radlog(L_ERR,"Fatal. Fail to disconnect DB. Error :%s\n",sock->lasterror); - } + int i; + fb_commit(sock); + + if (fb_disconnect(sock)) { + radlog(L_ERR, "Fatal. Fail to disconnect DB. Error :%s\n", + sock->lasterror); + } + #ifdef _PTHREAD_H - pthread_mutex_destroy (&sock->mut); + pthread_mutex_destroy (&sock->mut); #endif - for (i=0; irow_fcount;i++) free(sock->row[i]); - free(sock->row);free(sock->row_sizes); - fb_free_sqlda(sock->sqlda_out); - free(sock->sqlda_out); - free(sock->tpb); - free(sock->dpb); - if (sock->lasterror) free(sock->lasterror); - memset(sock,0,sizeof(rlm_sql_firebird_sock)); + for (i=0; irow_fcount;i++) { + free(sock->row[i]); + } + + free(sock->row);free(sock->row_sizes); + fb_free_sqlda(sock->sqlda_out); + + free(sock->sqlda_out); + free(sock->tpb); + free(sock->dpb); + + if (sock->lasterror) { + free(sock->lasterror); + } + + memset(sock,0,sizeof(rlm_sql_firebird_sock)); }