]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/console/conio.c
- Use different share mode when opening files on WinMe/98/95 since
[bacula/bacula] / bacula / src / console / conio.c
index fee692718ece3edeeb8c5a5f3ec41c464c34c79e..7a65d2ab99d5b94924aaaca0bcac02cd8712d501 100755 (executable)
@@ -10,6 +10,7 @@
 */
 /*
    Copyright (C) 1981-2004 Kern Sibbald and John Walker
+                Yes, that is 1981 no error.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
 
  */
 
+/* 
+ * UTF-8
+ *  If the top bit of a UTF-8 string is 0 (8 bits), then it
+ *    is a normal ASCII character.
+ *  If the top two bits are 11 (i.e. (c & 0xC0) == 0xC0 then
+ *    it is the start of a series of chars (up to 5)
+ *  Each subsequent character starts with 10 (i.e. (c & 0xC0) == 0x80)
+ */
+
 
 #ifdef TEST_PROGRAM
 #include <stdio.h>
 #endif
 
 #include <termios.h>
+#ifdef HAVE_SUN_OS
+extern "C" int tgetent(void *, const char *);
+extern "C" int tgetnum(const char *);
+extern "C" char *tgetstr (const char*, char**);
+extern "C" char *tgoto (const char *, int, int);
+#else
 #include <termcap.h>
+#endif
 #include "func.h"
 
 
@@ -53,14 +70,17 @@ extern char *BC;
 extern char *UP;
 
 /* Forward referenced functions */
+extern "C" {
 static void sigintcatcher(int);
+}
+
 static void add_smap(char *str, int func);
 
 
 /* Global variables */
 
-static char *t_up = "\n";                    /* scroll up character */
-static char *t_honk = "\007";                /* sound beep */
+static const char *t_up = "\n";                    /* scroll up character */
+static const char *t_honk = "\007";                /* sound beep */
 static char *t_il;                          /* insert line */
 static char *t_dl;                          /* delete line */
 static char *t_cs;                          /* clear screen */
@@ -177,12 +197,6 @@ static short char_map[600]= {
   };
 
 
-#define NVID  0x1E                   /* normal video -- blue */
-#define RVID  0x4F                   /* reverse video -- red */
-#define MNVID 0x07                   /* normal video (monochrome tube) */
-#define MRVID 0x70                   /* reverse video (monochrome tube) */
-
-
 /* Local variables */
 
 #define CR '\r'                       /* carriage return */
@@ -190,11 +204,12 @@ static short char_map[600]= {
 
 /* Function Prototypes */
 
-static int input_char(void);
-static int t_gnc(void);
+static unsigned int input_char(void);
+static unsigned int t_gnc(void);
 static void insert_space(char *curline, int line_len);
-static void forward(int i, char *str, int str_len);
-static void backup(int i);
+static void insert_hole(char *curline, int line_len);
+static void forward(char *str, int str_len);
+static void backup(char *curline);
 static void delchr(int cnt, char *curline, int line_len);
 static int iswordc(char c);
 static int  next_word(char *ldb_buf);
@@ -208,22 +223,26 @@ static void t_honk_horn(void);
 static void t_insert_line(void);
 static void t_delete_line(void);
 static void t_clrline(int pos, int width);
-void t_sendl(char *msg, int len);
-void t_send(char *msg);
+void t_sendl(const char *msg, int len);
+void t_send(const char *msg);
 void t_char(char c);
 static void asclrs();
 static void ascurs(int y, int x);
 
 static void rawmode(FILE *input);
 static void normode(void);
-static int t_getch();
+static unsigned t_getch();
 static void asclrl(int pos, int width);
 static void asinsl();
 static void asdell();
 
 int input_line(char *string, int length);
+extern "C" {
 void con_term();
+}
 void trapctlc();
+int usrbrk();
+void clrbrk();
     
 void con_init(FILE *input)
 {
@@ -291,22 +310,23 @@ char *bstrncpy(char *dest, const char *src, int maxlen)
 /*
  * New style string mapping to function code
  */
-static int do_smap(int c)
+static unsigned do_smap(unsigned c)
 {
     char str[MAX_STAB];
     int len = 0; 
     stab_t *tstab;
     int i, found;
+    unsigned cm;
 
     len = 1;
     str[0] = c;
     str[1] = 0;
 
-    if (c != 27) {
-       c = char_map[c];
-    }
-    if (c <= 0) {
+    cm = char_map[c];
+    if (cm == 0) {
        return c;
+    } else {
+       c = cm;
     }
     for ( ;; ) {
        found = 0;
@@ -393,10 +413,10 @@ static void add_smap(char *str, int func)
 
 /* Get the next character from the terminal - performs table lookup on
    the character to do the desired translation */
-static int
+static unsigned int
 input_char()
 {
-    int c;
+    unsigned c;
 
     if ((c=t_gnc()) <= 599) {        /* IBM generates codes up to 260 */
          c = do_smap(c);
@@ -422,185 +442,285 @@ input_char()
 int
 input_line(char *string, int length)
 {
-   char curline[200];                /* edit buffer */
+   char curline[2000];               /* edit buffer */
    int noline;
-   int c;
+   unsigned c;
+   int more;
+   int i;
 
     if (first) {
-       poolinit();                   /* build line pool */
-       first = 0;
+       poolinit();                  /* build line pool */
+       first = 0;
     }
     noline = 1;                      /* no line fetched yet */
     for (cl=cp=0; cl<length && cl<(int)sizeof(curline); ) {
-       switch (c=(int)input_char()) {
-       case F_RETURN:                /* CR */
-            t_sendl("\r\n", 2);       /* yes, print it and */
-           goto done;                /* get out */
-       case F_CLRSCRN:               /* clear screen */
-          asclrs();
-          t_sendl(curline, cl);
-          ascurs(0, cp);
+       if (usrbrk()) {
+         clrbrk();
+         break;
+       }
+       switch (c=input_char()) {
+       case F_RETURN:               /* CR */
+           t_sendl("\r\n", 2);       /* yes, print it and */
+          goto done;                /* get out */
+       case F_CLRSCRN:              /* clear screen */
+         asclrs();
+         t_sendl(curline, cl);
+         ascurs(0, cp);
+         break;
+       case F_CSRUP:
+          if (noline) {             /* no line fetched yet */
+              getnext();            /* getnext so getprev gets current */
+              noline = 0;           /* we now have line */
+          }
+          bstrncpy(curline, getprev(), sizeof(curline));
+          prtcur(curline);
           break;
-       case F_CSRUP:
-           if (noline) {             /* no line fetched yet */
-               getnext();            /* getnext so getprev gets current */
-               noline = 0;           /* we now have line */
-           }
-           bstrncpy(curline, getprev(), sizeof(curline));
-           prtcur(curline);
-           break;
-       case F_CSRDWN:
-           noline = 0;               /* mark line fetched */
-           bstrncpy(curline, getnext(), sizeof(curline));
-           prtcur(curline);
-           break;
-       case F_INSCHR:
-           insert_space(curline, sizeof(curline));
-           break;
-       case F_DELCHR:
-           delchr(1, curline, sizeof(curline));       /* delete one character */
-           break;
-       case F_CSRLFT:                /* Backspace */
-           backup(1);
-           break;
-       case F_CSRRGT:
-           forward(1,curline, sizeof(curline));
-           break;
-       case F_ERSCHR:                /* Rubout */
-           backup(1);
-           delchr(1, curline, sizeof(curline));
-           break;
-       case F_DELEOL:
-           t_clrline(0, t_width);
-           if (cl > cp)
-               cl = cp;
-           break;
-       case F_NXTWRD:
-           forward(next_word(curline),curline, sizeof(curline));
-           break;
-       case F_PRVWRD:
-           backup(prev_word(curline));
-           break;
-       case F_DELWRD:
-           delchr(next_word(curline), curline, sizeof(curline)); /* delete word */
-           break;
-       case F_NXTMCH:                /* Ctl-X */
-           if (cl==0) {
-               *string = EOS;        /* terminate string */
-               return(c);            /* give it to him */
-           }
-           /* Note fall through */
-       case F_DELLIN:
-       case F_ERSLIN:
-           backup(cp);               /* backup to beginning of line */
-           t_clrline(0,t_width);     /* erase line */
-           cp = 0;
-           cl = 0;                   /* reset cursor counter */
-           break;
-       case F_SOL:
-           backup(cp);
-           break;
-       case F_EOL:
-           while (cp < cl) {
-               forward(1,curline, sizeof(curline));
-           }
-           while (cp > cl) {
-               backup(1);
-           }
-           break;
-       case F_TINS:                  /* toggle insert mode */
-           mode_insert = !mode_insert;  /* flip bit */
-           break;
-       default:
-           if (c > 255) {            /* function key hit */
-               if (cl==0) {          /* if first character then */
-                   *string = EOS;         /* terminate string */
-                   return c;              /* return it */
-               }
-               t_honk_horn();        /* complain */
-           } else {
-               if (mode_insert) {
-                   insert_space(curline, sizeof(curline));
-               }
-               curline[cp++] = c;    /* store character in line being built */
-               t_char((char)c);      /* echo character to terminal */
-               if (cp > cl) {
-                   cl = cp;          /* keep current length */
-               }
-           }
-           break;
-       }                             /* end switch */
+       case F_CSRDWN:
+          noline = 0;               /* mark line fetched */
+          bstrncpy(curline, getnext(), sizeof(curline));
+          prtcur(curline);
+          break;
+       case F_INSCHR:
+          insert_space(curline, sizeof(curline));
+          break;
+       case F_DELCHR:
+          delchr(1, curline, sizeof(curline));       /* delete one character */
+          break;
+       case F_CSRLFT:               /* Backspace */
+          backup(curline);
+          break;
+       case F_CSRRGT:
+          forward(curline, sizeof(curline));
+          break;
+       case F_ERSCHR:               /* Rubout */
+          backup(curline);
+          delchr(1, curline, sizeof(curline));
+          break;
+       case F_DELEOL:
+          t_clrline(0, t_width);
+          if (cl > cp)
+              cl = cp;
+          break;
+       case F_NXTWRD:
+          i = next_word(curline);
+          while (i--) {
+             forward(curline, sizeof(curline));
+          }
+          break;
+       case F_PRVWRD:
+          i = prev_word(curline);
+          while (i--) {
+             backup(curline);
+          }
+          break;
+       case F_DELWRD:
+          delchr(next_word(curline), curline, sizeof(curline)); /* delete word */
+          break;
+       case F_NXTMCH:               /* Ctl-X */
+          if (cl==0) {
+              *string = EOS;        /* terminate string */
+              return(c);            /* give it to him */
+          }
+          /* Note fall through */
+       case F_DELLIN:
+       case F_ERSLIN:
+          while (cp > 0) {
+             backup(curline);      /* backup to beginning of line */
+          }
+          t_clrline(0,t_width);     /* erase line */
+          cp = 0;
+          cl = 0;                   /* reset cursor counter */
+          break;
+       case F_SOL:
+          while (cp > 0) {
+             backup(curline);
+          }
+          break;
+       case F_EOL:
+          while (cp < cl) {
+              forward(curline, sizeof(curline));
+          }
+          while (cp > cl) {
+              backup(curline);
+          }
+          break;
+       case F_TINS:                 /* toggle insert mode */
+          mode_insert = !mode_insert;  /* flip bit */
+          break;
+       default:
+          if (c > 255) {            /* function key hit */
+              if (cl==0) {          /* if first character then */
+                 *string = EOS;     /* terminate string */
+                 return c;          /* return it */
+              }
+              t_honk_horn();        /* complain */
+          } else {
+              if ((c & 0xC0) == 0xC0) {
+                 if ((c & 0xFC) == 0xFC) {
+                    more = 5;
+                 } else if ((c & 0xF8) == 0xF8) {
+                    more = 4;
+                 } else if ((c & 0xF0) == 0xF0) {
+                    more = 3;
+                 } else if ((c & 0xE0) == 0xE0) {
+                    more = 2;
+                 } else {
+                    more = 1;
+                 }
+              } else {
+                 more = 0;
+              }
+              if (mode_insert) {
+                 insert_space(curline, sizeof(curline));
+              }
+              curline[cp++] = c;    /* store character in line being built */
+              t_char(c);      /* echo character to terminal */
+              while (more--) {
+                 c= input_char();  
+                 insert_hole(curline, sizeof(curline));
+                 curline[cp++] = c;    /* store character in line being built */
+                 t_char(c);      /* echo character to terminal */
+              }
+              if (cp > cl) {
+                 cl = cp;           /* keep current length */
+                 curline[cp] = 0;
+              }
+          }
+          break;
+       }                            /* end switch */
     }
 /* If we fall through here rather than goto done, the line is too long
    simply return what we have now. */
 done:
-    curline[cl++] = EOS;             /* terminate */
-    bstrncpy(string,curline,length);          /* return line to caller */
-    /* Note, put line zaps curline */
-    putline(curline,cl);             /* save line for posterity */
-    return 0;                        /* give it to him/her */
+   curline[cl++] = EOS;             /* terminate */
+   bstrncpy(string,curline,length);          /* return line to caller */
+   /* Note, put line zaps curline */
+   putline(curline,cl);             /* save line for posterity */
+   return 0;                        /* give it to him/her */
 }
 
 /* Insert a space at the current cursor position */
 static void
 insert_space(char *curline, int curline_len)
 {
-    int i;
-
-    if (cp > cl || cl+1 > curline_len) return;
-    /* Note! source and destination overlap */
-    memmove(&curline[cp+1],&curline[cp],i=cl-cp);
-    cl++;
-    i++;
-    curline[cp] = ' ';
-    forward(i,curline, curline_len);
-    backup(i);
+   int i;
+
+   if (cp > cl || cl+1 > curline_len) {
+      return;
+   }
+   /* Note! source and destination overlap */
+   memmove(&curline[cp+1],&curline[cp],i=cl-cp);
+   cl++;
+   curline[cp] = ' ';
+   i = 0;
+   while (cl > cp) {
+      forward(curline, curline_len);
+      i++;
+   }
+   while (i--) {
+      backup(curline);
+   }
+}
+
+
+static void
+insert_hole(char *curline, int curline_len)
+{
+   int i;
+
+   if (cp > cl || cl+1 > curline_len) {
+      return;
+   }
+   /* Note! source and destination overlap */
+   memmove(&curline[cp+1], &curline[cp], i=cl-cp);
+   cl++;
+   curline[cl] = 0;
 }
 
 
 /* Move cursor forward keeping characters under it */
 static void
-forward(int i,char *str, int str_len)
+forward(char *str, int str_len)
 {
-    while (i--) {
-       if (cp > str_len) {
-          return;
-       }
-       if (cp>=cl) {
-            t_char(' ');
-            str[cp+1] = ' ';
-       } else {
-           t_char(str[cp]);
-       }
-       cp++;
-    }
+   if (cp > str_len) {
+      return;
+   }
+   if (cp >= cl) {
+       t_char(' ');
+       str[cp+1] = ' ';
+       str[cp+2] = 0;
+   } else {
+       t_char(str[cp]);
+       if ((str[cp] & 0xC0) == 0xC0) {
+         cp++;
+         while ((str[cp] & 0xC0) == 0x80) {
+            t_char(str[cp]);
+            cp++;
+         }
+         cp--;
+       }
+   }
+   cp++;
+}
+
+/* How many characters under the cursor */
+static int 
+char_count(int cptr, char *str)
+{
+   int cnt = 1;
+   if (cptr > cl) {
+      return 0;
+   }
+   if ((str[cptr] & 0xC0) == 0xC0) {
+      cptr++;
+      while ((str[cptr] & 0xC0) == 0x80) {
+        cnt++;
+        cptr++;
+      }
+   }
+   return cnt;
 }
 
 /* Backup cursor keeping characters under it */
 static void
-backup(int i)
+backup(char *str) 
 {
-    for ( ;i && cp; i--,cp--)
-        t_char('\010');
+    if (cp == 0) {
+       return;
+    }
+    while ((str[cp] & 0xC0) == 0x80) {
+       cp--;
+    }
+    t_char('\010');
+    cp--;
 }
 
 /* Delete the character under the cursor */
 static void
-delchr(int cnt, char *curline, int line_len) 
+delchr(int del, char *curline, int line_len) 
 {
-    register int i;
+   int i, cnt;
 
-    if (cp > cl)
-       return;
-    if ((i=cl-cp-cnt+1) > 0) {
-       memcpy(&curline[cp],&curline[cp+cnt],i);
-    }
-    curline[cl -= cnt] = EOS;
-    t_clrline(0,t_width);
-    if (cl > cp) {
-       forward(i=cl-cp,curline, line_len);
-       backup(i);
-    }
+   if (cp > cl || del == 0) {
+      return;
+   }
+   while (del-- && cp > 0) {
+      cnt = char_count(cp, curline);
+      if ((i=cl-cp-cnt) > 0) {
+        memcpy(&curline[cp], &curline[cp+cnt], i);
+      }
+      cl -= cnt;
+      curline[cl] = EOS;
+      t_clrline(0, t_width);
+      i = 0;
+      while (cl > cp) {
+        forward(curline, line_len);
+        i++;
+      }
+      while (i--) {
+        backup(curline);
+      }
+   }
 }
 
 /* Determine if character is part of a word */
@@ -610,9 +730,9 @@ iswordc(char c)
    if (mode_wspace)
       return !isspace(c);
    if (c >= '0' && c <= '9')
-      return TRUE;
+      return true;
    if (c == '$' || c == '%')
-      return TRUE;
+      return true;
    return isalpha(c);
 }
 
@@ -620,14 +740,14 @@ iswordc(char c)
 static int
 next_word(char *ldb_buf)
 {
-    int ncp;
-
-    if (cp > cl)
-       return 0;
-    ncp = cp;
-    for ( ; ncp<cl && iswordc(*(ldb_buf+ncp)); ncp++) ;
-    for ( ; ncp<cl && !iswordc(*(ldb_buf+ncp)); ncp++) ;
-    return ncp-cp;
+   int ncp;
+
+   if (cp > cl)
+      return 0;
+   ncp = cp;
+   for ( ; ncp<cl && iswordc(*(ldb_buf+ncp)); ncp++) ;
+   for ( ; ncp<cl && !iswordc(*(ldb_buf+ncp)); ncp++) ;
+   return ncp-cp;
 }
 
 /* Return number of characters to get to previous word */
@@ -659,10 +779,12 @@ prev_word(char *ldb_buf)
 static void
 prtcur(char *str)
 {
-    backup(cp);
+    while (cp > 0) {
+       backup(str);
+    }
     t_clrline(0,t_width);
     cp = cl = strlen(str);
-    t_sendl(str,cl);
+    t_sendl(str, cl);
 }
 
 
@@ -670,12 +792,12 @@ prtcur(char *str)
 static void
 poolinit()
 {
-    slptr = lptr = (struct lstr *)pool;
-    lptr->nextl = lptr;
-    lptr->prevl = lptr;
-    lptr->used = 1;
-    lptr->line = 0;
-    lptr->len = POOLEN;
+   slptr = lptr = (struct lstr *)pool;
+   lptr->nextl = lptr;
+   lptr->prevl = lptr;
+   lptr->used = 1;
+   lptr->line = 0;
+   lptr->len = POOLEN;
 }
 
 
@@ -683,59 +805,59 @@ poolinit()
 static char *
 getnext()
 {
-    do {                             /* find next used line */
-       lptr = lptr->nextl;
-    } while (!lptr->used);
-    return (char *)&lptr->line;
+   do {                             /* find next used line */
+      lptr = lptr->nextl;
+   } while (!lptr->used);
+   return (char *)&lptr->line;
 }
 
 /* Return pointer to previous line in the pool */
 static char *
 getprev()
 {
-    do {                             /* find previous used line */
-       lptr = lptr->prevl;
-    } while (!lptr->used);
-    return (char *)&lptr->line;
+   do {                             /* find previous used line */
+      lptr = lptr->prevl;
+   } while (!lptr->used);
+   return (char *)&lptr->line;
 }
 
 static void
 putline(char *newl, int newlen)
 {
-    struct lstr *nptr;               /* points to next line */
-    char *p;
-
-    lptr = slptr;                    /* get ptr to last line stored */
-    lptr = lptr->nextl;              /* advance pointer */
-    if ((char *)lptr-pool+newlen+PHDRL > POOLEN) { /* not enough room */
-       lptr->used = 0;               /* delete line */
-       lptr = (struct lstr *)pool;   /* start at beginning of buffer */
-    }
-    while (lptr->len < newlen+PHDRL) { /* concatenate buffers */
-       nptr = lptr->nextl;           /* point to next line */
-       lptr->nextl = nptr->nextl;    /* unlink it from list */
-       nptr->nextl->prevl = lptr;
-       lptr->len += nptr->len;
-    }
-    if (lptr->len > newlen + 2 * PHDRL) { /* split buffer */
-       nptr = (struct lstr *)((char *)lptr + newlen + PHDRL);
-       /* Appropriate byte alignment - normally 2 byte, but on
-          sparc we need 4 byte alignment, so we always do 4 */
-       if (((unsigned)nptr & 3) != 0) { /* test four byte alignment */
-           p = (char *)nptr;
-           nptr = (struct lstr *)((((unsigned) p) & ~3) + 4);
-       }
-       nptr->len = lptr->len - ((char *)nptr - (char *)lptr);
-       lptr->len -= nptr->len;
-       nptr->nextl = lptr->nextl;    /* link in new buffer */
-       lptr->nextl->prevl = nptr;
-       lptr->nextl = nptr;
-       nptr->prevl = lptr;
-       nptr->used = 0;
-    }
-    memcpy(&lptr->line,newl,newlen);
-    lptr->used = 1;                  /* mark line used */
-    slptr = lptr;                    /* save as stored line */
+   struct lstr *nptr;               /* points to next line */
+   char *p;
+
+   lptr = slptr;                    /* get ptr to last line stored */
+   lptr = lptr->nextl;              /* advance pointer */
+   if ((char *)lptr-pool+newlen+PHDRL > POOLEN) { /* not enough room */
+       lptr->used = 0;              /* delete line */
+       lptr = (struct lstr *)pool;   /* start at beginning of buffer */
+   }
+   while (lptr->len < newlen+PHDRL) { /* concatenate buffers */
+       nptr = lptr->nextl;          /* point to next line */
+       lptr->nextl = nptr->nextl;    /* unlink it from list */
+       nptr->nextl->prevl = lptr;
+       lptr->len += nptr->len;
+   }
+   if (lptr->len > newlen + 2 * PHDRL) { /* split buffer */
+       nptr = (struct lstr *)((char *)lptr + newlen + PHDRL);
+       /* Appropriate byte alignment - normally 2 byte, but on
+         sparc we need 4 byte alignment, so we always do 4 */
+       if (((long unsigned)nptr & 3) != 0) { /* test four byte alignment */
+          p = (char *)nptr;
+          nptr = (struct lstr *)((((long unsigned) p) & ~3) + 4);
+       }
+       nptr->len = lptr->len - ((char *)nptr - (char *)lptr);
+       lptr->len -= nptr->len;
+       nptr->nextl = lptr->nextl;    /* link in new buffer */
+       lptr->nextl->prevl = nptr;
+       lptr->nextl = nptr;
+       nptr->prevl = lptr;
+       nptr->used = 0;
+   }
+   memcpy(&lptr->line,newl,newlen);
+   lptr->used = 1;                  /* mark line used */
+   slptr = lptr;                    /* save as stored line */
 }
 
 #ifdef DEBUGOUT
@@ -754,21 +876,21 @@ dump(struct lstr *ptr, char *msg)
 static void
 t_honk_horn()
 {
-    t_send(t_honk);
+   t_send(t_honk);
 }
 
 /* Insert line on terminal */
 static void
 t_insert_line()
 {
-    asinsl();
+   asinsl();
 }
 
 /* Delete line from terminal */
 static void
 t_delete_line()
 {
-    asdell();
+   asdell();
 }
 
 /* clear line from pos to width */
@@ -780,9 +902,9 @@ t_clrline(int pos, int width)
 
 /* Helper function to add string preceded by 
  *  ESC to smap table */
-static void add_esc_smap(char *str, int func)
+static void add_esc_smap(const char *str, int func)
 {
-   char buf[100];
+   char buf[1000];
    buf[0] = 0x1B;                    /* esc */
    bstrncpy(buf+1, str, sizeof(buf)-1);
    add_smap(buf, func);
@@ -834,10 +956,12 @@ static void rawmode(FILE *input)
 
    if (!termtype) {
       printf("Cannot get terminal type.\n");
+      normode();
       exit(1);
    }
    if (tgetent(term_buffer, termtype) < 0) {
       printf("Cannot get terminal termcap entry.\n");
+      normode();
       exit(1);
    }
    t_width = t_height = -1;
@@ -896,13 +1020,6 @@ static void rawmode(FILE *input)
    add_esc_smap("[4~",  F_EOF);
    add_esc_smap("f",    F_NXTWRD);
    add_esc_smap("b",    F_PRVWRD);
-
-
-#ifdef needed
-   for (i=301; i<600; i++) {
-      char_map[i] = i;               /* setup IBM function codes */
-   }
-#endif
 }
 
 
@@ -916,7 +1033,7 @@ static void normode()
 }
 
 /* Get next character from terminal/script file/unget buffer */
-static int
+static unsigned
 t_gnc()
 {
     return t_getch();
@@ -924,41 +1041,30 @@ t_gnc()
 
 
 /* Get next character from OS */
-static int t_getch(void)
+static unsigned t_getch(void)
 {
-   char c;
+   unsigned char c;
 
    if (read(0, &c, 1) != 1) {
       c = 0;
    }
-   return (int)c;   
+   return (unsigned)c;  
 }
     
-#ifdef xxx
-
-/* window_size -- Return window height and width to caller. */
-static int window_size(int *height, int *width)        /* /window_size/ */
-{
-   *width = tgetnum("co") - 1;
-   *height = tgetnum("li");
-   return 1;
-}
-#endif
-
 /* Send message to terminal - primitive routine */
 void
-t_sendl(char *msg,int len)
+t_sendl(const char *msg, int len)
 {
-    write(1, msg, len);
+   write(1, msg, len);
 }
 
 void
-t_send(char *msg)
+t_send(const char *msg)
 {
-    if (msg == NULL) {
-       return;
-    }
-    t_sendl(msg, strlen(msg));   /* faster than one char at time */
+   if (msg == NULL) {
+      return;
+   }
+   t_sendl(msg, strlen(msg));   /* faster than one char at time */
 }
 
 /* Send single character to terminal - primitive routine - */
@@ -988,7 +1094,8 @@ void clrbrk()
 static void sigintcatcher(int sig)
 {
    brkflg++;
-   if (brkflg > 1) {
+   if (brkflg > 3) {
+      normode();
       exit(1);
    }
    signal(SIGINT, sigintcatcher);
@@ -1005,22 +1112,22 @@ void trapctlc()
 /* ASCLRL() -- Clear to end of line from current position */
 static void asclrl(int pos, int width) 
 {
-    int i;
+   int i;
 
-    if (t_cl) {
-       t_send(t_cl);                 /* use clear to eol function */
-       return;
-    }
-    if (pos==1 && linsdel_ok) {
-       t_delete_line();              /* delete line */
-       t_insert_line();              /* reinsert it */
-       return;
-    }
-    for (i=1; i<=width-pos+1; i++)
-        t_char(' ');                  /* last resort, blank it out */
-    for (i=1; i<=width-pos+1; i++)    /* backspace to original position */
-       t_char(0x8);
-    return;
+   if (t_cl) {
+       t_send(t_cl);                /* use clear to eol function */
+       return;
+   }
+   if (pos==1 && linsdel_ok) {
+       t_delete_line();             /* delete line */
+       t_insert_line();             /* reinsert it */
+       return;
+   }
+   for (i=1; i<=width-pos+1; i++)
+       t_char(' ');                  /* last resort, blank it out */
+   for (i=1; i<=width-pos+1; i++)    /* backspace to original position */
+       t_char(0x8);
+   return;
   
 }