Reformatting in firebird
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 2 Mar 2013 21:41:31 +0000 (16:41 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 2 Mar 2013 21:41:45 +0000 (16:41 -0500)
src/modules/rlm_sql/drivers/rlm_sql_firebird/rlm_sql_firebird.c
src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.c

index 935a2e6..32ed1a3 100644 (file)
@@ -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 */
index bf85808..39a9896 100644 (file)
@@ -27,81 +27,110 @@ RCSID("$Id$")
 #include <stdarg.h>
 
 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; i<count; i++) {
-    sock->tpb[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; i<sqlda->sqld; 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; 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;
- }
+       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_fcount<sock->sqlda_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<sock->row_fcount) {
-     sock->row[i]=0;
-     sock->row_sizes[i++]=0;
-   }
- }
-
-for (i=0, var=sock->sqlda_out->sqlvar; i<sock->sqlda_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_fcount<sock->sqlda_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 <sock->row_fcount) {
+                       sock->row[i] = 0;
+                       sock->row_sizes[i++] = 0;
+               }
+       }
+
+       for (i=0, var=sock->sqlda_out->sqlvar; i<sock->sqlda_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, &times);
+                       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, &times);
+                       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, &times);
+                       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, &times);
-               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, &times);
-               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, &times);
-               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->sqln<sock->sqlda_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->sqln<sock->sqlda_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; i<sock->row_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; i<sock->row_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));
 }