]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/cats/myingres.c
As we have a multithreaded application let tell that to esqlcc so it can optimize...
[bacula/bacula] / bacula / src / cats / myingres.c
index c72f72a58d72af110155ea5ae0da3a54b877ac07..48a797a66df2de4c4f1679692f75a5308646c713 100644 (file)
@@ -1,8 +1,39 @@
+/*
+   Bacula® - The Network Backup Solution
+   Copyright (C) 2009-2010 Free Software Foundation Europe e.V.
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version two of the GNU General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+   Bacula® is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ * Bacula Catalog Database routines specific to Ingres
+ *   These are Ingres specific routines
+ *
+ *    Stefan Reddig, June 2009
+ */
 #include "bacula.h"
-/* # line 3 "myingres.sc" */
+/* # line 37 "myingres.sc" */  
 #ifdef HAVE_INGRES
+#include <eqpname.h>
+#include <eqdefcc.h>
 #include <eqsqlca.h>
-    extern IISQLCA sqlca;   /* SQL Communications Area */
+IISQLCA *IIsqlca();
+#define sqlca (*(IIsqlca()))
 #include <eqsqlda.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -15,68 +46,75 @@ int INGcheck()
 {
    return (sqlca.sqlcode < 0) ? sqlca.sqlcode : 0;
 }
-short INGgetCols(const char *stmt)
+short INGgetCols(const char *query)
 {
-/* # line 23 "myingres.sc" */  
+/* # line 57 "myingres.sc" */  
   
-  char *stmtd;
-/* # line 25 "myingres.sc" */  
+  char *stmt;
+/* # line 59 "myingres.sc" */  
   
    short number = 1;
    IISQLDA *sqlda;
    sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE));
    memset(sqlda, 0, (IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE)));
    sqlda->sqln = number;
-   stmtd = (char*)malloc(strlen(stmt)+1);
-   strncpy(stmtd,stmt,strlen(stmt)+1);
-/* # line 38 "myingres.sc" */  /* prepare */
+   stmt = bstrdup(query);
+/* # line 71 "myingres.sc" */  /* prepare */
   {
     IIsqInit(&sqlca);
-    IIsqPrepare(0,(char *)"s1",(char *)0,0,stmtd);
+    IIsqPrepare(0,(char *)"s1",(char *)0,0,stmt);
   }
-/* # line 39 "myingres.sc" */  /* host code */
+/* # line 72 "myingres.sc" */  /* host code */
    if (INGcheck() < 0) {
-      free(stmtd);
-      free(sqlda);
-      return -1;
+      number = -1;
+      goto bail_out;
    }
-/* # line 44 "myingres.sc" */  /* describe */
+/* # line 77 "myingres.sc" */  /* describe */
   {
     IIsqInit(&sqlca);
     IIsqDescribe(0,(char *)"s1",sqlda,0);
   }
-/* # line 45 "myingres.sc" */  /* host code */
+/* # line 78 "myingres.sc" */  /* host code */
    if (INGcheck() < 0) {
-      free(stmtd);
-      free(sqlda);
-      return -1;
+      number = -1;
+      goto bail_out;
    }
    number = sqlda->sqld;
-   free(stmtd); free(sqlda);
+bail_out:
+   free(stmt);
+   free(sqlda);
    return number;
 }
-IISQLDA *INGgetDescriptor(short numCols, const char *stmt)
+static inline IISQLDA *INGgetDescriptor(short numCols, const char *query)
 {
-/* # line 58 "myingres.sc" */  
+/* # line 93 "myingres.sc" */  
   
-  char *stmtd;
-/* # line 60 "myingres.sc" */  
+  char *stmt;
+/* # line 95 "myingres.sc" */  
   
    int i;
    IISQLDA *sqlda;
    sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE));
    memset(sqlda, 0, (IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE)));
    sqlda->sqln = numCols;
-   stmtd = (char *)malloc(strlen(stmt)+1);
-   strncpy(stmtd,stmt,strlen(stmt)+1);
-/* # line 73 "myingres.sc" */  /* prepare */
+   stmt = bstrdup(query);
+/* # line 107 "myingres.sc" */ /* prepare */
   {
     IIsqInit(&sqlca);
-    IIsqPrepare(0,(char *)"s2",sqlda,0,stmtd);
+    IIsqPrepare(0,(char *)"s2",sqlda,0,stmt);
   }
-/* # line 75 "myingres.sc" */  /* host code */
-   free(stmtd);
+/* # line 109 "myingres.sc" */ /* host code */
+   free(stmt);
    for (i = 0; i < sqlda->sqld; ++i) {
+      /*
+       * Negative type indicates nullable coulumns, so an indicator
+       * is allocated, otherwise it's null
+       */
+      if (sqlda->sqlvar[i].sqltype > 0) {
+         sqlda->sqlvar[i].sqlind = NULL;
+      } else {
+         sqlda->sqlvar[i].sqlind = (short *)malloc(sizeof(short));
+      }
       /*
        * Alloc space for variable like indicated in sqllen
        * for date types sqllen is always 0 -> allocate by type
@@ -92,23 +130,33 @@ IISQLDA *INGgetDescriptor(short numCols, const char *stmt)
          sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN);
          break;
       default:
-         sqlda->sqlvar[i].sqldata = (char *)malloc(sqlda->sqlvar[i].sqllen);
+         /*
+          * plus one to avoid zero mem allocs
+          */
+         sqlda->sqlvar[i].sqldata = (char *)malloc(sqlda->sqlvar[i].sqllen+1);
          break;
       }
    }
    return sqlda;
 }
-void INGfreeDescriptor(IISQLDA *sqlda)
+static void INGfreeDescriptor(IISQLDA *sqlda)
 {
    int i;
+   if (!sqlda) {
+      return;
+   }
    for (i = 0; i < sqlda->sqld; ++i) {
-      free(sqlda->sqlvar[i].sqldata);
-      free(sqlda->sqlvar[i].sqlind);
+      if (sqlda->sqlvar[i].sqldata) {
+         free(sqlda->sqlvar[i].sqldata);
+      }
+      if (sqlda->sqlvar[i].sqlind) {
+         free(sqlda->sqlvar[i].sqlind);
+      }
    }
    free(sqlda);
    sqlda = NULL;
 }
-int INGgetTypeSize(IISQLVAR *ingvar)
+static inline int INGgetTypeSize(IISQLVAR *ingvar)
 {
    int inglength = 0;
    /*
@@ -127,10 +175,13 @@ int INGgetTypeSize(IISQLVAR *ingvar)
    }
    return inglength;
 }
-INGresult *INGgetINGresult(IISQLDA *sqlda)
+static inline INGresult *INGgetINGresult(IISQLDA *sqlda)
 {
    int i;
    INGresult *result = NULL;
+   if (!sqlda) {
+      return NULL;
+   }
    result = (INGresult *)malloc(sizeof(INGresult));
    memset(result, 0, sizeof(INGresult));
    result->sqlda = sqlda;
@@ -139,48 +190,64 @@ INGresult *INGgetINGresult(IISQLDA *sqlda)
    result->first_row = NULL;
    result->status = ING_EMPTY_RESULT;
    result->act_row = NULL;
-   strcpy(result->numrowstring,"");
+   memset(result->numrowstring, 0, sizeof(result->numrowstring));
    if (result->num_fields) {
       result->fields = (INGRES_FIELD *)malloc(sizeof(INGRES_FIELD) * result->num_fields);
       memset(result->fields, 0, sizeof(INGRES_FIELD) * result->num_fields);
       for (i = 0; i < result->num_fields; ++i) {
          memset(result->fields[i].name, 0, 34);
-         strncpy(result->fields[i].name, sqlda->sqlvar[i].sqlname.sqlnamec, sqlda->sqlvar[i].sqlname.sqlnamel);
+         bstrncpy(result->fields[i].name, sqlda->sqlvar[i].sqlname.sqlnamec, sqlda->sqlvar[i].sqlname.sqlnamel);
          result->fields[i].max_length = INGgetTypeSize(&sqlda->sqlvar[i]);
          result->fields[i].type = abs(sqlda->sqlvar[i].sqltype);
-         result->fields[i].flags = (abs(sqlda->sqlvar[i].sqltype)<0) ? 1 : 0;
+         result->fields[i].flags = (sqlda->sqlvar[i].sqltype < 0) ? 1 : 0;
       }
    }
    return result;
 }
-void INGfreeINGresult(INGresult *ing_res)
+static inline void INGfreeRowSpace(ING_ROW *row, IISQLDA *sqlda)
+{
+   int i;
+   if (row == NULL || sqlda == NULL) {
+      return;
+   }
+   for (i = 0; i < sqlda->sqld; ++i) {
+      if (row->sqlvar[i].sqldata) {
+         free(row->sqlvar[i].sqldata);
+      }
+      if (row->sqlvar[i].sqlind) {
+         free(row->sqlvar[i].sqlind);
+      }
+   }
+   free(row->sqlvar);
+   free(row);
+}
+static void INGfreeINGresult(INGresult *ing_res)
 {
    int rows;
    ING_ROW *rowtemp;
+   if (!ing_res) {
+      return;
+   }
    /*
     * Free all rows and fields, then res, not descriptor!
+    *
+    * Use of rows is a nasty workaround til I find the reason,
+    * why aggregates like max() don't work
     */
-   if (ing_res != NULL) {
-      /*
-       * Use of rows is a nasty workaround til I find the reason,
-       * why aggregates like max() don't work
-       */
-      rows = ing_res->num_rows;
-      ing_res->act_row = ing_res->first_row;
-      while (ing_res->act_row != NULL && rows > 0) {
-         rowtemp = ing_res->act_row->next;
-         INGfreeRowSpace(ing_res->act_row, ing_res->sqlda);
-         ing_res->act_row = rowtemp;
-         --rows;
-      }
-      if (ing_res->fields) {
-         free(ing_res->fields);
-      }
+   rows = ing_res->num_rows;
+   ing_res->act_row = ing_res->first_row;
+   while (ing_res->act_row != NULL && rows > 0) {
+      rowtemp = ing_res->act_row->next;
+      INGfreeRowSpace(ing_res->act_row, ing_res->sqlda);
+      ing_res->act_row = rowtemp;
+      --rows;
+   }
+   if (ing_res->fields) {
+      free(ing_res->fields);
    }
    free(ing_res);
-   ing_res = NULL;
 }
-ING_ROW *INGgetRowSpace(INGresult *ing_res)
+static inline ING_ROW *INGgetRowSpace(INGresult *ing_res)
 {
    int i;
    unsigned short len; /* used for VARCHAR type length */
@@ -198,100 +265,96 @@ ING_ROW *INGgetRowSpace(INGresult *ing_res)
        * Make strings out of the data, then the space and assign 
        * (why string? at least it seems that way, looking into the sources)
        */
-      switch (ing_res->fields[i].type) {
-      case IISQ_VCH_TYPE:
-         len = ((ING_VARCHAR *)sqlda->sqlvar[i].sqldata)->len;
-         vars[i].sqldata = (char *)malloc(len+1);
-         memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata+2,len);
-         vars[i].sqldata[len] = '\0';
-         break;
-      case IISQ_CHA_TYPE:
-         vars[i].sqldata = (char *)malloc(ing_res->fields[i].max_length+1);
-         memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata,sqlda->sqlvar[i].sqllen);
-         vars[i].sqldata[ing_res->fields[i].max_length] = '\0';
-         break;
-      case IISQ_INT_TYPE:
-         vars[i].sqldata = (char *)malloc(20);
-         memset(vars[i].sqldata, 0, 20);
-         switch (sqlda->sqlvar[i].sqllen) {
-         case 2:
-            snprintf(vars[i].sqldata, 20, "%d",*(short*)sqlda->sqlvar[i].sqldata);
+      vars[i].sqlind = (short *)malloc(sizeof(short));
+      if (sqlda->sqlvar[i].sqlind) {
+         memcpy(vars[i].sqlind,sqlda->sqlvar[i].sqlind,sizeof(short));
+      } else {
+         *vars[i].sqlind = NULL;
+      }
+      /*
+       * if sqlind pointer exists AND points to -1 -> column is 'null'
+       */
+      if ( *vars[i].sqlind && (*vars[i].sqlind == -1)) {
+         vars[i].sqldata = NULL;
+      } else {
+         switch (ing_res->fields[i].type) {
+         case IISQ_VCH_TYPE:
+            len = ((ING_VARCHAR *)sqlda->sqlvar[i].sqldata)->len;
+            vars[i].sqldata = (char *)malloc(len+1);
+            memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata+2,len);
+            vars[i].sqldata[len] = '\0';
+            break;
+         case IISQ_CHA_TYPE:
+            vars[i].sqldata = (char *)malloc(ing_res->fields[i].max_length+1);
+            memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata,sqlda->sqlvar[i].sqllen);
+            vars[i].sqldata[ing_res->fields[i].max_length] = '\0';
+            break;
+         case IISQ_INT_TYPE:
+            vars[i].sqldata = (char *)malloc(20);
+            memset(vars[i].sqldata, 0, 20);
+            switch (sqlda->sqlvar[i].sqllen) {
+            case 2:
+               bsnprintf(vars[i].sqldata, 20, "%d",*(short*)sqlda->sqlvar[i].sqldata);
+               break;
+            case 4:
+               bsnprintf(vars[i].sqldata, 20, "%ld",*(int*)sqlda->sqlvar[i].sqldata);
+               break;
+            case 8:
+               bsnprintf(vars[i].sqldata, 20, "%lld",*(long*)sqlda->sqlvar[i].sqldata);
+               break;
+            }
             break;
-         case 4:
-            snprintf(vars[i].sqldata, 20, "%d",*(int*)sqlda->sqlvar[i].sqldata);
+         case IISQ_TSTMP_TYPE:
+            vars[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN+1);
+            vars[i].sqldata[IISQ_TSTMP_LEN] = '\0';
             break;
-         case 8:
-            snprintf(vars[i].sqldata, 20, "%d",*(long*)sqlda->sqlvar[i].sqldata);
+         case IISQ_TSWO_TYPE:
+            vars[i].sqldata = (char *)malloc(IISQ_TSWO_LEN+1);
+            vars[i].sqldata[IISQ_TSWO_LEN] = '\0';
+            break;
+         case IISQ_TSW_TYPE:
+            vars[i].sqldata = (char *)malloc(IISQ_TSW_LEN+1);
+            vars[i].sqldata[IISQ_TSW_LEN] = '\0';
             break;
          }
-         break;
-      case IISQ_TSTMP_TYPE:
-         vars[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN+1);
-         vars[i].sqldata[IISQ_TSTMP_LEN] = '\0';
-         break;
-      case IISQ_TSWO_TYPE:
-         vars[i].sqldata = (char *)malloc(IISQ_TSWO_LEN+1);
-         vars[i].sqldata[IISQ_TSWO_LEN] = '\0';
-         break;
-      case IISQ_TSW_TYPE:
-         vars[i].sqldata = (char *)malloc(IISQ_TSW_LEN+1);
-         vars[i].sqldata[IISQ_TSW_LEN] = '\0';
-         break;
       }
-      vars[i].sqlind = (short *)malloc(sizeof(short));
-      memcpy(vars[i].sqlind,sqlda->sqlvar[i].sqlind,sizeof(short));
    }
    return row;
 }
-void INGfreeRowSpace(ING_ROW *row, IISQLDA *sqlda)
-{
-   int i;
-   if (row == NULL || sqlda == NULL) {
-      return;
-   }
-   for (i = 0; i < sqlda->sqld; ++i) {
-      free(row->sqlvar[i].sqldata);
-      free(row->sqlvar[i].sqlind);
-   }
-   free(row->sqlvar);
-   free(row);
-}
-int INGfetchAll(const char *stmt, INGresult *ing_res)
+static inline int INGfetchAll(const char *query, INGresult *ing_res)
 {
    int linecount = 0;
    ING_ROW *row;
    IISQLDA *desc;
    int check = -1;
    desc = ing_res->sqlda;
-/* # line 292 "myingres.sc" */ /* host code */
+/* # line 363 "myingres.sc" */ /* host code */
    if ((check = INGcheck()) < 0) {
       return check;
    }
-/* # line 296 "myingres.sc" */ /* open */
+/* # line 367 "myingres.sc" */ /* open */
   {
     IIsqInit(&sqlca);
-    IIcsOpen((char *)"c2",1824,27390);
+    IIcsOpen((char *)"c2",19318,7414);
     IIwritio(0,(short *)0,1,32,0,(char *)"s2");
-    IIcsQuery((char *)"c2",1824,27390);
+    IIcsQuery((char *)"c2",19318,7414);
   }
-/* # line 297 "myingres.sc" */ /* host code */
+/* # line 368 "myingres.sc" */ /* host code */
    if ((check = INGcheck()) < 0) {
       return check;
    }
    /* for (linecount = 0; sqlca.sqlcode == 0; ++linecount) */
-   while(sqlca.sqlcode == 0) {
-/* # line 303 "myingres.sc" */ /* fetch */
+   do {
+/* # line 374 "myingres.sc" */ /* fetch */
   {
     IIsqInit(&sqlca);
-    if (IIcsRetScroll((char *)"c2",1824,27390,-1,-1) != 0) {
+    if (IIcsRetScroll((char *)"c2",19318,7414,-1,-1) != 0) {
       IIcsDaGet(0,desc);
       IIcsERetrieve();
     } /* IIcsRetrieve */
   }
-/* # line 304 "myingres.sc" */ /* host code */
-      if ((check = INGcheck()) < 0) { return check;}
-      if (sqlca.sqlcode == 0)
-      {
+/* # line 376 "myingres.sc" */ /* host code */
+      if ( (sqlca.sqlcode == 0) || (sqlca.sqlcode == -40202) ) {
          row = INGgetRowSpace(ing_res); /* alloc space for fetched row */
          /*
           * Initialize list when encountered first time
@@ -306,25 +369,28 @@ int INGfetchAll(const char *stmt, INGresult *ing_res)
          row->row_number = linecount;
          ++linecount;
       }
-   }
-/* # line 325 "myingres.sc" */ /* close */
+   } while ( (sqlca.sqlcode == 0) || (sqlca.sqlcode == -40202) );
+/* # line 394 "myingres.sc" */ /* close */
   {
     IIsqInit(&sqlca);
-    IIcsClose((char *)"c2",1824,27390);
+    IIcsClose((char *)"c2",19318,7414);
   }
-/* # line 327 "myingres.sc" */ /* host code */
+/* # line 396 "myingres.sc" */ /* host code */
    ing_res->status = ING_COMMAND_OK;
    ing_res->num_rows = linecount;
    return linecount;
 }
-ING_STATUS INGresultStatus(INGresult *res)
+static inline ING_STATUS INGresultStatus(INGresult *res)
 {
-   if (res == NULL) {return ING_NO_RESULT;}
-   return res->status;
+   if (res == NULL) {
+      return ING_NO_RESULT;
+   } else {
+      return res->status;
+   }
 }
-void INGrowSeek(INGresult *res, int row_number)
+static void INGrowSeek(INGresult *res, int row_number)
 {
-   ING_ROW *trow;
+   ING_ROW *trow = NULL;
    if (res->act_row->row_number == row_number) {
       return;
    }
@@ -347,12 +413,12 @@ char *INGgetvalue(INGresult *res, int row_number, int column_number)
    }
    return res->act_row->sqlvar[column_number].sqldata;
 }
-int INGgetisnull(INGresult *res, int row_number, int column_number)
+bool INGgetisnull(INGresult *res, int row_number, int column_number)
 {
    if (row_number != res->act_row->row_number) {
       INGrowSeek(res, row_number);
    }
-   return (short)*res->act_row->sqlvar[column_number].sqlind;
+   return (*res->act_row->sqlvar[column_number].sqlind == -1) ? true : false;
 }
 int INGntuples(const INGresult *res)
 {
@@ -377,31 +443,30 @@ short INGftype(const INGresult *res, int column_number)
 int INGexec(INGconn *conn, const char *query)
 {
    int check;
-/* # line 402 "myingres.sc" */ 
+/* # line 477 "myingres.sc" */ 
   
   int rowcount;
   char *stmt;
-/* # line 405 "myingres.sc" */ 
+/* # line 480 "myingres.sc" */ 
   
-   stmt = (char *)malloc(strlen(query)+1);
-   strncpy(stmt,query,strlen(query)+1);
+   stmt = bstrdup(query);
    rowcount = -1;
-/* # line 411 "myingres.sc" */ /* execute */
+/* # line 485 "myingres.sc" */ /* execute */
   {
     IIsqInit(&sqlca);
     IIsqExImmed(stmt);
     IIsyncup((char *)0,0);
   }
-/* # line 412 "myingres.sc" */ /* host code */
+/* # line 487 "myingres.sc" */ /* host code */
    free(stmt);
    if ((check = INGcheck()) < 0) {
       return check;
    }
-/* # line 417 "myingres.sc" */ /* inquire_ingres */
+/* # line 493 "myingres.sc" */ /* inquire_ingres */
   {
     IILQisInqSqlio((short *)0,1,30,sizeof(rowcount),&rowcount,8);
   }
-/* # line 418 "myingres.sc" */ /* host code */
+/* # line 494 "myingres.sc" */ /* host code */
    if ((check = INGcheck()) < 0) {
       return check;
    }
@@ -417,9 +482,16 @@ INGresult *INGquery(INGconn *conn, const char *query)
    int rows = -1;
    int cols = INGgetCols(query);
    desc = INGgetDescriptor(cols, query);
+   if (!desc) {
+      return NULL;
+   }
    res = INGgetINGresult(desc);
+   if (!res) {
+      return NULL;
+   }
    rows = INGfetchAll(query, res);
    if (rows < 0) {
+     INGfreeDescriptor(desc);
      INGfreeINGresult(res);
      return NULL;
    }
@@ -430,35 +502,35 @@ void INGclear(INGresult *res)
    if (res == NULL) {
       return;
    }
-   IISQLDA *desc = res->sqlda;
+   INGfreeDescriptor(res->sqlda);
    INGfreeINGresult(res);
-   INGfreeDescriptor(desc);
 }
 INGconn *INGconnectDB(char *dbname, char *user, char *passwd)
 {
+   INGconn *dbconn;
    if (dbname == NULL || strlen(dbname) == 0) {
       return NULL;
    }
-   INGconn *dbconn = (INGconn *)malloc(sizeof(INGconn));
+   dbconn = (INGconn *)malloc(sizeof(INGconn));
    memset(dbconn, 0, sizeof(INGconn));
-/* # line 465 "myingres.sc" */ 
+/* # line 553 "myingres.sc" */ 
   
   char ingdbname[24];
   char ingdbuser[32];
   char ingdbpasw[32];
   char conn_name[32];
   int sess_id;
-/* # line 471 "myingres.sc" */ 
+/* # line 559 "myingres.sc" */ 
   
-   strcpy(ingdbname,dbname);
+   bstrncpy(ingdbname, dbname, sizeof(ingdbname));
    if (user != NULL) {
-      strcpy(ingdbuser,user);
+      bstrncpy(ingdbuser, user, sizeof(ingdbuser));
       if (passwd != NULL) {
-         strcpy(ingdbpasw,passwd);
+         bstrncpy(ingdbpasw, passwd, sizeof(ingdbpasw));
       } else {
-         strcpy(ingdbpasw, "");
+         memset(ingdbpasw, 0, sizeof(ingdbpasw));
       }
-/* # line 482 "myingres.sc" */ /* connect */
+/* # line 570 "myingres.sc" */ /* connect */
   {
     IIsqInit(&sqlca);
     IIsqUser(ingdbuser);
@@ -466,30 +538,30 @@ INGconn *INGconnectDB(char *dbname, char *user, char *passwd)
     (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, 
     (char *)0, (char *)0, (char *)0, (char *)0);
   }
-/* # line 486 "myingres.sc" */ /* host code */
+/* # line 574 "myingres.sc" */ /* host code */
    } else {
-/* # line 487 "myingres.sc" */ /* connect */
+/* # line 575 "myingres.sc" */ /* connect */
   {
     IIsqInit(&sqlca);
     IIsqConnect(0,ingdbname,(char *)0, (char *)0, (char *)0, (char *)0, 
     (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, 
     (char *)0, (char *)0, (char *)0);
   }
-/* # line 488 "myingres.sc" */ /* host code */
+/* # line 576 "myingres.sc" */ /* host code */
    }   
-/* # line 490 "myingres.sc" */ /* inquire_sql */
+/* # line 578 "myingres.sc" */ /* inquire_sql */
   {
     IILQisInqSqlio((short *)0,1,32,31,conn_name,13);
   }
-/* # line 491 "myingres.sc" */ /* inquire_sql */
+/* # line 579 "myingres.sc" */ /* inquire_sql */
   {
     IILQisInqSqlio((short *)0,1,30,sizeof(sess_id),&sess_id,11);
   }
-/* # line 493 "myingres.sc" */ /* host code */
-   strncpy(dbconn->dbname, ingdbname, sizeof(dbconn->dbname));
-   strncpy(dbconn->user, ingdbuser, sizeof(dbconn->user));
-   strncpy(dbconn->password, ingdbpasw, sizeof(dbconn->password));
-   strncpy(dbconn->connection_name, conn_name, sizeof(dbconn->connection_name));
+/* # line 581 "myingres.sc" */ /* host code */
+   bstrncpy(dbconn->dbname, ingdbname, sizeof(dbconn->dbname));
+   bstrncpy(dbconn->user, ingdbuser, sizeof(dbconn->user));
+   bstrncpy(dbconn->password, ingdbpasw, sizeof(dbconn->password));
+   bstrncpy(dbconn->connection_name, conn_name, sizeof(dbconn->connection_name));
    dbconn->session_id = sess_id;
    dbconn->msg = (char*)malloc(257);
    memset(dbconn->msg, 0, 257);
@@ -497,15 +569,19 @@ INGconn *INGconnectDB(char *dbname, char *user, char *passwd)
 }
 void INGdisconnectDB(INGconn *dbconn)
 {
-   /*
-    * TODO: check for any real use of dbconn: maybe whenn multithreaded?
-    */
-/* # line 509 "myingres.sc" */ /* disconnect */
+/* # line 594 "myingres.sc" */ 
+  
+  int sess_id;
+/* # line 596 "myingres.sc" */ 
+  
+   sess_id = dbconn->session_id;
+/* # line 600 "myingres.sc" */ /* disconnect */
   {
     IIsqInit(&sqlca);
+    IILQsidSessID(sess_id);
     IIsqDisconnect();
   }
-/* # line 510 "myingres.sc" */ /* host code */
+/* # line 602 "myingres.sc" */ /* host code */
    if (dbconn != NULL) {
       free(dbconn->msg);
       free(dbconn);
@@ -513,17 +589,17 @@ void INGdisconnectDB(INGconn *dbconn)
 }
 char *INGerrorMessage(const INGconn *conn)
 {
-/* # line 518 "myingres.sc" */ 
+/* # line 610 "myingres.sc" */ 
   
   char errbuf[256];
-/* # line 520 "myingres.sc" */ 
+/* # line 612 "myingres.sc" */ 
   
-/* # line 522 "myingres.sc" */ /* inquire_ingres */
+/* # line 614 "myingres.sc" */ /* inquire_ingres */
   {
     IILQisInqSqlio((short *)0,1,32,255,errbuf,63);
   }
-/* # line 523 "myingres.sc" */ /* host code */
-   memcpy(conn->msg,&errbuf,256);
+/* # line 615 "myingres.sc" */ /* host code */
+   memcpy(conn->msg, &errbuf, 256);
    return conn->msg;
 }
 char *INGcmdTuples(INGresult *res)
@@ -534,5 +610,5 @@ char *INGcmdTuples(INGresult *res)
 int INGputCopyEnd(INGconn *conn, const char *errormsg);
 int INGputCopyData(INGconn *conn, const char *buffer, int nbytes);
 */
-/* # line 537 "myingres.sc" */ 
+/* # line 629 "myingres.sc" */ 
 #endif