]> git.mdlowis.com Git - projs/tide.git/commitdiff
fixed password prompt handling and added escape code handling/filtering
authorMichael D. Lowis <mike@mdlowis.com>
Mon, 25 Nov 2019 01:13:54 +0000 (20:13 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Mon, 25 Nov 2019 01:13:54 +0000 (20:13 -0500)
src/lib/xpty.c

index 6c4dfbfd458f926d1cf2f5a439c671dee959afe3..922a8c0406e75308cf33b8ff0f76e405756b873d 100644 (file)
@@ -9,9 +9,88 @@
     #include <util.h>
 #endif
 
+#define BUFFERSZ 16384
+
 static View* EditView = NULL;
 static int Pty_Fd = -1;
 
+char ReadBuf[BUFFERSZ+1] = {0};
+char ArgsBuf[BUFFERSZ+1] = {0};
+char InputBuf[BUFFERSZ+1] = {0};
+ssize_t ArgsPos = 0;
+ssize_t InputPos = 0;
+
+static enum {
+    READ_CHAR = 0,
+    READ_ESC,
+    READ_OSC,
+    READ_OSI,
+} State = READ_CHAR;
+
+static void read_char(char c)
+{
+    if (c == '\033')
+    {
+        State = READ_ESC;
+    }
+    else
+    {
+        InputBuf[InputPos++] = c;
+        InputBuf[InputPos] = '\0';
+    }
+}
+
+static void read_esc(char c)
+{
+    if (c == '[')
+   {
+        State = READ_OSI;
+   }
+   else
+    if (c == ']')
+   {
+        State = READ_OSC;
+   }
+   else
+   {
+        State = READ_CHAR;
+   }
+}
+
+static void read_osc(char c)
+{
+    if (c == '\a')
+    {
+        State = READ_CHAR;
+        if (ArgsBuf[0] == '7' && ArgsBuf[1] == ';')
+        {
+            chdir(&ArgsBuf[2]);
+        }
+        ArgsPos = 0;
+        ArgsBuf[0] = '\0';
+    }
+    else
+    {
+        ArgsBuf[ArgsPos++] = c;
+        ArgsBuf[ArgsPos] = '\0';
+    }
+}
+
+static void read_osi(char c)
+{
+    if (isalpha(c))
+    {
+        State = READ_CHAR;
+    }
+}
+
+static void (*Handlers[])(char c) = {
+    [READ_CHAR] = read_char,
+    [READ_ESC] = read_esc,
+    [READ_OSC] = read_osc,
+    [READ_OSI] = read_osi,
+};
+
 static void putb(int byte)
 {
     struct termios tio = {0};
@@ -25,8 +104,13 @@ static void putb(int byte)
         {
             *((char*)(EditView->buffer.contents.gapstart-1)) = '*';
         }
+        else
+        {
+            *((char*)(EditView->buffer.contents.gapstart-1)) = ' ';
+            EditView->buffer.point.beg = EditView->buffer.point.end;
+        }
     }
-    if (byte == '\n' && buf_inpoint(&(EditView->buffer), EditView->buffer.selection.end-1))
+    else if (byte == '\n' && buf_inpoint(&(EditView->buffer), EditView->buffer.selection.end-1))
     {
         /* get the input string and update the point */
         char* str = buf_getsat(&(EditView->buffer), EditView->buffer.point.beg, EditView->buffer.point.end);
@@ -44,27 +128,19 @@ static void putb(int byte)
 
 static void writedata(char* buf, long n)
 {
-    char data[16384];
-    int p = 0;
-    for (int i = 0; i < n; i++)
+    InputBuf[0] = '\0';
+    InputPos = 0;
+    for (long i = 0; i < n; i++)
     {
-        if (buf[i] == '\033')
-        {
-        }
-        else
-        {
-            data[p++] = buf[i];
-            data[p] = '\0';
-        }
+        Handlers[State](buf[i]);
     }
-    view_putraw(EditView, data);
+    view_putraw(EditView, InputBuf);
     EditView->sync_flags |= CURSOR;
 }
 
 static void xpty_read(Job* job)
 {
-    char buffer[16385];
-    long nread = read(job->fd, buffer, sizeof(buffer)-1);
+    long nread = read(job->fd, ReadBuf, sizeof(ReadBuf)-1);
     if (nread <= 0)
     {
         job->readfn = NULL;
@@ -74,7 +150,7 @@ static void xpty_read(Job* job)
     }
     else if (nread > 0)
     {
-        buffer[nread] = '\0';
+        ReadBuf[nread] = '\0';
 
         /* swap the point and selection to perform the insert */
         size_t start = EditView->buffer.point.beg;
@@ -88,7 +164,7 @@ static void xpty_read(Job* job)
         EditView->buffer.point = sel;
 
         /* insert the text */
-        writedata(buffer, nread);
+        writedata(ReadBuf, nread);
 
         /* adjust the original selection and swap it back */
         nread = (EditView->buffer.point.end - start);
@@ -137,12 +213,6 @@ int xpty_run(View* view, char** cmd)
             view->buffer.oninsert = putb;
             view->buffer.point.beg = view->buffer.selection.end;
             view->buffer.point.end = view->buffer.selection.end;
-//            struct termios tio;
-//            tcgetattr(Pty_Fd, &tio);
-//            tio.c_lflag &= ~(ECHO | ECHONL);
-//            tio.c_cc[ VMIN ]  = 1;
-//            tio.c_cc[ VTIME ] = 0;
-//            tcsetattr(Pty_Fd, TCSANOW, &tio);
             job_spawn(Pty_Fd, xpty_read, NULL, NULL);
         }
     }