https://gitlab.com/jessp011/gqlplus/-/merge_requests/1

Adapted not to change version number (1.14 -> 1.18)

diff --git a/configure.ac b/configure.ac
index bb192d17fd1b4089068fedf1e2e1287c95249eff..6da50669d7aaf8303ad5de9554a5b3acbe5bcc94 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,7 @@
-AC_INIT([gqlplus], [1.14])
+AC_INIT([gqlplus], [1.14],kernel01@gmail.com)
 AC_CONFIG_SRCDIR([gqlplus.c])
 AM_INIT_AUTOMAKE
+AC_PROG_MAKE_SET
 AC_PROG_CC
 AC_PROG_INSTALL
 AC_PROG_RANLIB
diff --git a/gqlplus.c b/gqlplus.c
index 41a6db258ca6b1ed67cbf0dc121ccf1ee92ab875..81602ffd7a1c1cf197d0140332b0b529f7454692 100644
--- a/gqlplus.c
+++ b/gqlplus.c
@@ -440,9 +440,11 @@ Copyright (C) 2004 Ljubomir J. Buturovic. All Rights Reserved.
 #include <unistd.h>
 #include <ctype.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <strings.h>
 #include <stdio.h>
+#include <sys/time.h>
 #include <sys/types.h>
 #include <signal.h>
 #include <fcntl.h>
@@ -557,13 +559,19 @@ Copyright (C) 2004 Ljubomir J. Buturovic. All Rights Reserved.
 
 void save_history(void)
 {
+  int ret;
+
   if (history_list() == NULL)
     /* If history is of length 0 (because set as is or slave is not executable) */
     unlink(histname);
   else {
     write_history(histname);
-    chmod(histname, 0600);
-    printf("\nSession history saved to: %s\n", histname);
+    ret = chmod(histname, 0600);
+    if (ret < 0) {
+      fprintf(stderr, "Problem with chmod on %s\n", histname);
+    } else {
+      printf("\nSession history saved to: %s\n", histname);
+    }
   }
 }
 
@@ -626,6 +634,7 @@ int startsWith(char* szOrg, const char* szPrefix)
     if (strstr(szOrgTrimmed, szPrefix) == szOrgTrimmed){
       iMatch = 1;
     }
+    free(szOrgTrimmed);
   }
   return iMatch;
 }
@@ -650,6 +659,7 @@ int matchCommand(char* szOrg, char* szPrefix, char* szCmd)
       char* szRemaining = szOrgTrimmed + strlen(szPrefix);
       iMatch = startsWith(szRemaining, szCmd);
     }
+    free(szOrgTrimmed);
   }
 
   return iMatch;
@@ -871,6 +881,58 @@ static int check_password_prompt(char *str)
   return check_prompt;
 }
 
+/*
+  Send your command "cmd" to SQLPlus.
+  If it doesn't work exit with return code "ret" and inform user with "msg".
+  If "ret" is 0 then the caller handles error.
+*/
+int send_cmd(int outfd, int ret, char *cmd, char *msg)
+{
+  int status = write(outfd, cmd, strlen(cmd));
+
+  if ((status == -1) && (ret != 0)){
+    fprintf(stderr, "%s\n",msg);
+    exit(ret);
+  }
+
+  return(status);
+}
+
+/*
+  To avoid memory leaks build the error message.
+  Note: You need to free the message yourself after potentially using it.
+*/
+char *make_msg(const char *fmt, ...)
+{
+  int len;
+  char *buf = NULL;
+  va_list args;
+
+    /* find out how big a buffer we need */
+  va_start(args, fmt);
+  len = vsnprintf(buf, 0, fmt, args);
+  va_end(args);
+  len++;
+
+  buf = malloc(len * sizeof(char));
+  if (buf == NULL)
+  {
+    fprintf(stderr,"Out of memory when constructing error message.\n");
+    exit(-ENOMEM);
+  }
+
+  va_start(args, fmt);
+  len = vsnprintf(buf, len - 1, fmt, args);
+  va_end(args);
+  if (len < 0)
+  {
+    fprintf(stderr,"Out of memory when constructing error message.\n");
+    exit(-ENOMEM);
+  }
+
+  return(buf);
+}
+
 /*
    Get sqlplus output from `fd' and display it (*outstr is NULL)
    without prompt, or store it in *outstr. The prompt is returned and
@@ -880,7 +942,6 @@ static int check_password_prompt(char *str)
 static char *get_sqlplus(int fd, char *line, char **outstr)
 {
   int  done;
-  int  cntr;
   int  nread = 0;
   int  plen;
   int  llen;
@@ -888,6 +949,7 @@ static char *get_sqlplus(int fd, char *line, char **outstr)
   int  capacity;
   int  ocapacity;
   int  pdiff;
+  int  status;
   char *lline;
   char *xtr;
   char *last_line;
@@ -896,7 +958,6 @@ static char *get_sqlplus(int fd, char *line, char **outstr)
   char *prompt = (char *) 0;
 
   done = 0;
-  cntr = 0;
   capacity = INIT_LINE_LENGTH;
   ocapacity = INIT_LINE_LENGTH;
      
@@ -980,7 +1041,9 @@ static char *get_sqlplus(int fd, char *line, char **outstr)
         if (!outstr)
         {
           if (plen > 0)
-            write(STDOUT_FILENO, lline, plen);
+          {
+            status = write(STDOUT_FILENO, lline, plen);
+          }
         }
         else
         {
@@ -1029,7 +1092,9 @@ static char *get_sqlplus(int fd, char *line, char **outstr)
     if (!outstr)
     {
       if (llen > 0)
-        write(STDOUT_FILENO, lline, llen);
+      {
+        status = write(STDOUT_FILENO, lline, llen);
+      }
     }
     else 
     {
@@ -1163,6 +1228,7 @@ static char *accept_cmd(char *cmd, int fdin, int fdout, char *sql_prompt, char *
     printf("%s", fline);
     fflush(stdout);
     free(fline);
+    free(accept);
     prompt = strdup(sql_prompt);
   }else{
     /*
@@ -1172,15 +1238,11 @@ static char *accept_cmd(char *cmd, int fdin, int fdout, char *sql_prompt, char *
     /*
        Send it to sqlplus.
        */
-    write(fdout, rline, strlen(rline));
+    send_cmd(fdout, -1, rline, "sqlplus terminated - exiting...");
     /*
        Terminate the user input sent to sqlplus.
        */
-    status = write(fdout, "\n", 1);
-    if (status == -1){
-      fprintf(stderr, "sqlplus terminated - exiting...\n");
-      exit(-1);
-    }
+    send_cmd(fdout, -1, "\n", "sqlplus terminated - exiting...");
     /*
        Now read the message sent from sqlplus, which should be the SQL
        prompt. We don't display it, since that will be done by the
@@ -1279,13 +1341,11 @@ static int check_mode(mode_t st_mode)
 {
   int mode;
   mode_t mode1;
-  mode_t mode2;
 
   mode = 0;
   mode1 = S_ISREG(st_mode);
   if (mode1)
   {
-    mode2 = S_IXUSR;
     mode = st_mode & S_IXUSR;
   }
   return mode;
@@ -1358,7 +1418,17 @@ static char *search_exe(char *exe)
     {
       mode = check_mode(buf.st_mode);
       if (mode)
+      {
         path = lpath;
+      }
+      else
+      {
+        free(lpath);
+      }
+    }
+    else
+    {
+      free(lpath);
     }
   }
   return path;
@@ -1408,11 +1478,13 @@ char **get_environment(void)
 static void print_environment(char **enx)
 {
   int  idx;
-  char *env;
 
   idx = 0;
   while (enx[idx])
-    printf("enx[%d]: '%s'\n", idx, enx[idx++]);
+  {
+    printf("enx[%d]: '%s'\n", idx, enx[idx]);
+    idx++;
+  }
 }
 
 /*
@@ -1497,15 +1569,19 @@ static char *read_file(const char *fname, char *line)
       str = malloc((buf.st_size+1)*sizeof(char));
       if (str != (char *) 0){
         xtr = str;
-        while (fgets(line, MAX_LINE_LENGTH, fptr)){
+        while (NULL != fgets(line, MAX_LINE_LENGTH, fptr)){
           len = strlen(line);
           memcpy(xtr, line, len);
           xtr += len;
         }
-        fclose(fptr);
         *xtr = '\0';
       }
     }
+    fclose(fptr);
+  }
+  else
+  {
+    fprintf(stderr, "Could not read %s\n", fname);
   }
   return str;
 }
@@ -1578,7 +1654,7 @@ static char **file_editor(FILE *fptr, char *line)
 {
   char **editor = (char **) 0;
 
-  while (fgets(line, MAX_LINE_LENGTH, fptr) && (editor == (char **) 0))
+  while ((NULL != fgets(line, MAX_LINE_LENGTH, fptr)) && (editor == (char **) 0))
     if ((line[0] != '#') && strstr(line, DEFINE_CMD) && (strstr(line, EDITOR)))
       editor = set_editor(line);
   fclose(fptr);
@@ -1604,7 +1680,7 @@ static char **file_set_editor(char *line)
   char *oracle_home;
   FILE *fptr;
 
-  path = malloc(1024);
+  path = malloc(MAXPATHLEN * 2);
   /*
      Check local directory first.
      */
@@ -1669,7 +1745,8 @@ static void insert_line(int fdin, int fdout, char *xtr, char *ccmd, char *line)
   if (xtr && *xtr)
   {
     sprintf(ccmd, "i %s\n", xtr);
-    write(fdout, ccmd, strlen(ccmd));
+    send_cmd(fdout, -1, ccmd,
+              "sqlplus terminated while inserting line - exiting...");
     prompt = get_sqlplus(fdin, line, &str);
     free(prompt);
     free(str);
@@ -1703,9 +1780,12 @@ static void pause_cmd(int fdin, int fdout, char *line, char *sql_prompt, int fir
   int  flags;
   int  process_response;
   int  len;
+  int  ret;
+  char *err_msg;
   char *lx;
   char *response;
   char *sp;
+  char *tmp;
   char *prompt;
   char buffer[BUF_LEN];
 
@@ -1713,12 +1793,20 @@ static void pause_cmd(int fdin, int fdout, char *line, char *sql_prompt, int fir
      Get sqlplus output without blocking.
      */
   flags = fcntl(fdin, F_GETFL, 0);
-  fcntl(fdin, F_SETFL, (flags | O_NDELAY));
+  ret = fcntl(fdin, F_SETFL, (flags | O_NDELAY));
+  if (ret < 0)
+  {
+    fprintf(stderr, "Problem setting non blocking on sqlplus\n");
+  }
+
   /*
      Send the command to sqlplus.
      */
-  write(fdout, line, strlen(line));
-  write(fdout, "\n", 1);
+  err_msg = make_msg("sqlplus terminated while sending cmd |%s| exiting.",line);
+  send_cmd(fdout, -1, line, err_msg);
+  free(err_msg);
+  send_cmd(fdout, -1, "\n", "sqlplus terminated while sending cmd - exiting.");
+
   if (first_flag)
     process_response = 1;
   else
@@ -1802,8 +1890,11 @@ static void pause_cmd(int fdin, int fdout, char *line, char *sql_prompt, int fir
         /*
            Get a line from keyboard and send it to sqlplus.
            */
-        fgets(lx, MAX_LINE_LENGTH, stdin);
-        write(fdout, lx, strlen(lx));
+        tmp = fgets(lx, MAX_LINE_LENGTH, stdin);
+        err_msg = make_msg("sqlplus terminated while sending cmd |%s| exiting.",
+                            lx);
+        send_cmd(fdout, -1, lx, err_msg);
+        free(err_msg);
       }
     }
   }
@@ -1812,7 +1903,11 @@ static void pause_cmd(int fdin, int fdout, char *line, char *sql_prompt, int fir
   /*
      Reset pipe from sqlplus to O_NDELAY.
      */
-  fcntl(fdin, F_SETFL, (flags &~ O_NDELAY));
+  ret = fcntl(fdin, F_SETFL, (flags &~ O_NDELAY));
+  if (ret < 0)
+  {
+    fprintf(stderr,"Problem setting reseting blocking on sqlplus\n");
+  }
   free(lx);
   free(response);
 }
@@ -1843,7 +1938,7 @@ static int edit(int fdin, int fdout, char *line, char **editor, char *fname)
   char  *newline;
   char  **xrgs = (char **) 0;
   char  **enx = (char **) 0;
-  FILE  *fptr;
+  FILE  *fptr = NULL;
 
   status = 0;
   str = (char *) 0;
@@ -1869,8 +1964,10 @@ static int edit(int fdin, int fdout, char *line, char **editor, char *fname)
        Get last SQL statement from sqlplus and put it in afiedt.buf, then
        open it in editor.
        */
-    write(fdout, LIST_CMD, strlen(LIST_CMD));
+    send_cmd(fdout, -1, LIST_CMD,
+              "sqlplus terminated while sending LIST cmd - exiting.");
     prompt = get_sqlplus(fdin, line, &str);
+    free(prompt);
     /* TBD: afiedt.buf filename hardcoded. */
     rname = strdup(AFIEDT);
   }
@@ -1900,7 +1997,7 @@ static int edit(int fdin, int fdout, char *line, char **editor, char *fname)
       if (!status)
       {
         free(str);
-        free(prompt);
+        str = NULL;
         path = editor[0];
         xc = 0;
         while (editor[xc++] != (char *) 0);
@@ -1957,7 +2054,7 @@ static int edit(int fdin, int fdout, char *line, char **editor, char *fname)
         { 
           if (execve(path, xrgs, enx) < 0) 
           {
-            str = malloc(100);
+            str = malloc(strlen(path) + 19);
             sprintf(str, "execve() failure; %s", path);
             perror(str);
             _exit(-1);
@@ -1987,10 +2084,12 @@ static int edit(int fdin, int fdout, char *line, char **editor, char *fname)
               len -= 3;
               afiedt[len] = '\0';
             }
-            write(fdout, DEL_CMD, strlen(DEL_CMD));
+            send_cmd(fdout, -1, DEL_CMD,
+                      "sqlplus terminated while sending del cmd - exiting.");
             prompt = get_sqlplus(fdin, line, &str);
             free(prompt);
             free(str);
+            str = NULL;
             xtr = afiedt;
             ccmd = malloc(MAX_LINE_LENGTH*sizeof(char));
             while ((ptr = strchr(xtr, '\n')) != (char *) 0)
@@ -2007,7 +2106,8 @@ static int edit(int fdin, int fdout, char *line, char **editor, char *fname)
                Last line, if not empty.
                */
             insert_line(fdin, fdout, xtr, ccmd, line);
-            write(fdout, LIST_CMD, strlen(LIST_CMD));
+            send_cmd(fdout, -1, LIST_CMD,
+                      "sqlplus terminated while sending list cmd - exiting.");
             prompt = get_sqlplus(fdin, line, (char **) 0);
             free(prompt);
             free(ccmd);
@@ -2031,6 +2131,8 @@ static int edit(int fdin, int fdout, char *line, char **editor, char *fname)
   else
     write(STDOUT_FILENO, NOTHING_TO_SAVE, strlen(NOTHING_TO_SAVE));
   free(rname);
+  if (str)
+    free(str);
   return status;
 }
 
@@ -2103,6 +2205,7 @@ static char **parse_columns(char *str)
       }
     }
   }
+  free(tokens);
   return columns;
 }
 
@@ -2110,6 +2213,7 @@ static char **get_column_names(char *tablename, char *owner, int fdin, int fdout
 {
   int  len;
   char *ccmd = (char *) 0;
+  char *err_msg;
   char *str = (char *) 0;
   char *prompt = (char *) 0;
   char **columns = (char **) 0;
@@ -2124,7 +2228,11 @@ static char **get_column_names(char *tablename, char *owner, int fdin, int fdout
       sprintf(ccmd, "%s %s.%s\n", DESCRIBE, owner, tablename);
     else
       sprintf(ccmd, "%s %s\n", DESCRIBE, tablename);
-    write(fdout, ccmd, strlen(ccmd));
+
+    err_msg = make_msg("sqlplus terminated while sending cmd |%s| exiting.",
+                        ccmd);
+    send_cmd(fdout, -1, ccmd, err_msg);
+    free(err_msg);
     prompt = get_sqlplus(fdin, line, &str);
     free(prompt);
     columns = parse_columns(str);
@@ -2140,14 +2248,18 @@ static int get_pagesize(int fdin, int fdout, char *line)
   int  len;
   char *str;
   char *xtr;
+  char *prompt = (char *) 0;
 
-  write(fdout, PAGESIZE_CMD, strlen(PAGESIZE_CMD));
-  get_sqlplus(fdin, line, &str);
+  send_cmd(fdout, -1, PAGESIZE_CMD,
+            "sqlplus terminated while sending pagesize cmd - exiting.");
+
+  prompt = get_sqlplus(fdin, line, &str);
   xtr = strchr(str, ' ')+1;
   len = strspn(xtr, DIGITS);
   xtr[len] = '\0';
   pagesize = atoi(xtr);
   free(str);
+  free(prompt);
   return pagesize;
 }
 
@@ -2164,7 +2276,6 @@ static struct table *get_names(char *str, int fdin, int fdout, int pagesize, cha
   int  idx;
   int  capacity;
   char *tname;
-  char *ltr;
   char **toks;
   char **tokens;
   struct table *tables = NULL;
@@ -2184,15 +2295,11 @@ static struct table *get_names(char *str, int fdin, int fdout, int pagesize, cha
   if (pagesize > 0)
   {
     idx = 1;
-    ltr = (char *) 0;
   }
-  else
-    ltr = str;
   i = 0;
   while ((tname = toks[idx]))
   {
     idx++;
-    ltr = (char *) 0;
     if (*tname && strcmp(tname, "TABLE_NAME") && strcmp(tname, "VIEW_NAME") &&
         !strstr(tname, "------") && !strstr(tname, "rows selected"))
     {
@@ -2236,6 +2343,7 @@ static struct table *get_names(char *str, int fdin, int fdout, int pagesize, cha
       }
     }
   }
+  free(toks);
   if (fptr)
     fclose(fptr);
   return tables;
@@ -2248,6 +2356,8 @@ static struct table *get_names(char *str, int fdin, int fdout, int pagesize, cha
 static struct table *get_completion_names(int fdin, int fdout, char *line)
 {
   int  pagesize;
+  char *err_msg;
+  char *prompt;
   char *str;
   char *ccmd;
   struct table *tables;
@@ -2257,16 +2367,23 @@ static struct table *get_completion_names(int fdin, int fdout, char *line)
   pagesize = get_pagesize(fdin, fdout, line);
   ccmd = malloc((strlen(SELECT_TABLES_1)+strlen(SELECT_TABLES_2)+1)*sizeof(char));
   sprintf(ccmd, "%s%s", SELECT_TABLES_1, SELECT_TABLES_2);
-  write(fdout, ccmd, strlen(ccmd));
-  get_sqlplus(fdin, line, &str);
+  err_msg = make_msg("sqlplus terminated while sending cmd |%s| exiting.",ccmd);
+  send_cmd(fdout, -1, ccmd, err_msg);
+  free(err_msg);
+
+  prompt = get_sqlplus(fdin, line, &str);
   /* kehlet: ORA- error is likely because the database isn't open */
   if (!strstr(str, "ORA-")) {
     tables = get_names(str, fdin, fdout, pagesize, line);
   }
   free(str);
-  write(fdout, DEL_CMD, strlen(DEL_CMD));
-  get_sqlplus(fdin, line, &str);
+  free(prompt);
+  send_cmd(fdout, -1, DEL_CMD,
+            "sqlplus terminated while sending del cmd - exiting.");
+  prompt = get_sqlplus(fdin, line, &str);
   free(ccmd);
+  free(str);
+  free(prompt);
   return tables;
 }
 
@@ -2434,15 +2551,22 @@ static char *get_connect_string(int argc, char **argv)
       if (strchr(str, '/'))
       {
         if (strchr(str, '@'))
+        {
           connect_string = strdup(str);
+          break;
+        }
         else if (sid != (char *) 0)
         {
           connect_string = malloc(strlen(str)+strlen(sid)+2);
           sprintf(connect_string, "%s@%s", str, sid);
+          break;
         }
       }
       else
+      {
+        free(username);
         username = strdup(str);
+      }
     }
   }
   return connect_string;
@@ -2461,7 +2585,9 @@ static char *build_connect_string(char *user, char *password)
   if (strchr(user, '@'))
   {
     if (strchr(user, '/'))
+    {
       connect_string = strdup(user);
+    }
     else if ((password != (char *) 0))
     {
       tokens = str_tokenize(user, "@");
@@ -2506,15 +2632,29 @@ static char *get_sql_prompt(char *old_prompt, char *sqlplus, char *connect_strin
   char *cmd;
   char *xtr;
   char *ptr;
-  char tmpdir[500]="";
+  char tmpdir[MAXPATHLEN]="";
   char *env_tmpdir;
   int  fd;
 
   if (connect_string){
-    if (env_tmpdir=getenv("TMPDIR")){
-    }else if (env_tmpdir=getenv("TEMPDIR")){
-    }else{
-      env_tmpdir=getenv("TEMP");
+    if ((env_tmpdir=getenv("TMPDIR"))){
+        /* length "/gqlplus.XXXXXX" = 16 */
+      if (16 + strlen(env_tmpdir) > MAXPATHLEN) {
+        fprintf(stderr,"Environment variable TMPDIR too long\n");
+        env_tmpdir = (char *) 0;
+      }
+    }
+    if (!env_tmpdir && (env_tmpdir=getenv("TEMPDIR"))){
+      if (16 + strlen(env_tmpdir) > MAXPATHLEN) {
+        fprintf(stderr,"Environment variable TEMPDIR too long\n");
+        env_tmpdir = (char *) 0;
+      }
+    }
+    if (!env_tmpdir && (env_tmpdir=getenv("TEMP"))){
+      if (16 + strlen(env_tmpdir) > MAXPATHLEN) {
+        fprintf(stderr,"Environment variable TEMP too long\n");
+        env_tmpdir = (char *) 0;
+      }
     }
     if (env_tmpdir){
       strcpy(tmpdir, env_tmpdir);
@@ -2537,7 +2677,6 @@ static char *get_sql_prompt(char *old_prompt, char *sqlplus, char *connect_strin
     /*printf("cmd: `%s'\n", cmd);*/
     *status = system(cmd);
     if (!*status){
-      free(cmd);
       xtr = read_file(tmpdir, line);
       unlink(tmpdir);
       
@@ -2559,7 +2698,9 @@ static char *get_sql_prompt(char *old_prompt, char *sqlplus, char *connect_strin
           sqlprompt[len] = '\0';
         }
       }
+      free(xtr);
     }
+    free(cmd);
   }
   return sqlprompt;
 }
@@ -2606,6 +2747,7 @@ static void get_final_sqlplus(int fdin)
   int  result;
   int  capacity;
   int  llen;
+  int  ret;
   char *response;
   char buffer[BUF_LEN];
 
@@ -2618,7 +2760,13 @@ static void get_final_sqlplus(int fdin)
      Get sqlplus output without blocking.
      */
   flags = fcntl(fdin, F_GETFL, 0);
-  fcntl(fdin, F_SETFL, (flags | O_NDELAY));
+  ret = fcntl(fdin, F_SETFL, (flags | O_NDELAY));
+  if (ret < 0)
+  {
+    fprintf(stderr, "Problem setting non blocking on sqlplus\n");
+    perror(NULL);
+  }
+
   result = read(fdin, buffer, BUF_LEN);
   if (result > 0)
   {
@@ -2628,6 +2776,7 @@ static void get_final_sqlplus(int fdin)
     response[llen] = '\0';
   }
   printf("%s", response);
+  free(response);
 }
 
 /*
@@ -2651,8 +2800,10 @@ int main(int argc, char **argv)
   int    all_tables = 1; /* set to 0 if we cannot query or parse ALL_TABLES or ALL_VIEWS */
   int    pause_mode;
   int    pstat;
+  int    ret;
   char   *password = (char *) 0;
   char   *connect_string;
+  char   *err_msg;
   char   *path;
   char   *spath;
   char   *prompt;
@@ -2664,7 +2815,6 @@ int main(int argc, char **argv)
   char   *oline;
   char   *nptr;
   char   *shellcmd;
-  char   *accept;
   char   *ed;
   char   **editor;
   char   **xrgs;
@@ -2755,6 +2905,7 @@ int main(int argc, char **argv)
         {
           connect_string = get_connect_string(argc, argv);
           sql_prompt = get_sql_prompt(sql_prompt, spath, connect_string, line, &pstat);
+          free(connect_string);
         }
         else
           sql_prompt = SQL_PROMPT;
@@ -2791,7 +2942,7 @@ int main(int argc, char **argv)
                 xrgs[0] = spath;
                 if (execve(spath, xrgs, enx) < 0) 
                 {
-                  line = malloc(100);
+                  line = malloc(strlen(spath) + 19);
                   sprintf(line, "execve() failure; %s", spath);
                   perror(line);
                   status = -1;
@@ -2904,6 +3055,7 @@ int main(int argc, char **argv)
                       connect_string = build_connect_string(username, password);
                       sql_prompt = 
                         get_sql_prompt(sql_prompt, spath, connect_string, line, &pstat);
+                        free(connect_string);
                     }
                     else if (!check_password_prompt(prompt))
                       add_history(rline);
@@ -2919,8 +3071,11 @@ int main(int argc, char **argv)
                   if (!strncmp(lline, SET_CMD, strlen(SET_CMD)) && xrgs && xrgs[1] &&
                       !strncmp(xrgs[1], SQLPROMPT_CMD, 4))
                   {
-                    write(fds1[1], rline, strlen(rline));
-                    write(fds1[1], "\n", 1);
+                    err_msg = make_msg("sqlplus terminated while sending cmd |%s| exiting.",rline);
+                    send_cmd(fds1[1], -1, rline, err_msg);
+                    free(err_msg);
+                    send_cmd(fds1[1], -1, "\n",
+                      "sqlplus terminated while sending cmd - exiting.");
                     sql_prompt = set_sql_prompt(fds2[0], line);
                     prompt = strdup(sql_prompt);
                   }
@@ -2938,6 +3093,7 @@ int main(int argc, char **argv)
                         tokens = str_tokenize(oline,WHITESPACE);
                         connect_string = get_connect_string(2,tokens);
                         free(tokens);
+                        free(connect_string);
                       }
                     }
                     if (!strncmp(lline, DISCONNECT_CMD, 4))
@@ -2955,7 +3111,10 @@ int main(int argc, char **argv)
                     else if (xrgs && xrgs[1] && !strncmp(lline, SET_CMD, strlen(SET_CMD)) &&
                         !strncmp(xrgs[1], PAUSE_CMD, 3))
                     {
-                      write(fds1[1], rline, strlen(rline));
+                      err_msg = make_msg("sqlplus terminated while sending cmd |%s| exiting.",rline);
+                      send_cmd(fds1[1], -1, rline, err_msg);
+                      free(err_msg);
+
                       if (xrgs[2] && !strcmp(xrgs[2], ON_CMD))
                         pause_mode = 1;
                       else
@@ -2976,7 +3135,9 @@ int main(int argc, char **argv)
                        */
                     else if (!strncmp(lline, CLEAR_CMD, 2) && nptr &&
                         !strncmp(nptr, SCREEN, strlen(SCREEN)))
+                    {
                       system("clear");
+                    }
                     else if (!check_numeric_prompt(prompt) && (shellcmd = get_shellcmd(oline)))
                     {
                       system(shellcmd);
@@ -2986,16 +3147,20 @@ int main(int argc, char **argv)
                       if (check_password_prompt(prompt)){
                         status = tcsetattr(STDIN_FILENO, TCSAFLUSH, &save_termios);
                       }
-                      write(fds1[1], rline, strlen(rline));
+                      err_msg = make_msg("sqlplus terminated while sending cmd |%s| exiting.",rline);
+                      send_cmd(fds1[1], -1, rline, err_msg);
+                      free(err_msg);
+
                       if (strstr(lline, DEFINE_CMD) && (strstr(lline, EDITOR))){
                         editor = set_editor(lline);
                       }
                     }
                     free(prompt);
                     if (!quit_sqlplus){
-                      status = write(fds1[1], "\n", 1);
+                      status = send_cmd(fds1[1], 0, "\n",
+                                        "sqlplus terminated - exiting... :(");
+
                       if (status == -1){
-                        fprintf(stderr, "sqlplus terminated - exiting... :( \n");
                         quit_sqlplus = 1;
                       }else{