OSDN Git Service

Modify features and documents for 1.98b the urgent security release.
[ffftp/ffftp.git] / contrib / putty / LDISC.C
diff --git a/contrib/putty/LDISC.C b/contrib/putty/LDISC.C
deleted file mode 100644 (file)
index 119a02a..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/*\r
- * ldisc.c: PuTTY line discipline. Sits between the input coming\r
- * from keypresses in the window, and the output channel leading to\r
- * the back end. Implements echo and/or local line editing,\r
- * depending on what's currently configured.\r
- */\r
-\r
-#include <stdio.h>\r
-#include <ctype.h>\r
-\r
-#include "putty.h"\r
-#include "terminal.h"\r
-#include "ldisc.h"\r
-\r
-#define ECHOING (ldisc->cfg->localecho == FORCE_ON || \\r
-                 (ldisc->cfg->localecho == AUTO && \\r
-                      (ldisc->back->ldisc(ldisc->backhandle, LD_ECHO) || \\r
-                          term_ldisc(ldisc->term, LD_ECHO))))\r
-#define EDITING (ldisc->cfg->localedit == FORCE_ON || \\r
-                 (ldisc->cfg->localedit == AUTO && \\r
-                      (ldisc->back->ldisc(ldisc->backhandle, LD_EDIT) || \\r
-                          term_ldisc(ldisc->term, LD_EDIT))))\r
-\r
-static void c_write(Ldisc ldisc, char *buf, int len)\r
-{\r
-    from_backend(ldisc->frontend, 0, buf, len);\r
-}\r
-\r
-static int plen(Ldisc ldisc, unsigned char c)\r
-{\r
-    if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf(ldisc->term)))\r
-       return 1;\r
-    else if (c < 128)\r
-       return 2;                      /* ^x for some x */\r
-    else if (in_utf(ldisc->term) && c >= 0xC0)\r
-       return 1;                      /* UTF-8 introducer character\r
-                                       * (FIXME: combining / wide chars) */\r
-    else if (in_utf(ldisc->term) && c >= 0x80 && c < 0xC0)\r
-       return 0;                      /* UTF-8 followup character */\r
-    else\r
-       return 4;                      /* <XY> hex representation */\r
-}\r
-\r
-static void pwrite(Ldisc ldisc, unsigned char c)\r
-{\r
-    if ((c >= 32 && c <= 126) ||\r
-       (!in_utf(ldisc->term) && c >= 0xA0) ||\r
-       (in_utf(ldisc->term) && c >= 0x80)) {\r
-       c_write(ldisc, (char *)&c, 1);\r
-    } else if (c < 128) {\r
-       char cc[2];\r
-       cc[1] = (c == 127 ? '?' : c + 0x40);\r
-       cc[0] = '^';\r
-       c_write(ldisc, cc, 2);\r
-    } else {\r
-       char cc[5];\r
-       sprintf(cc, "<%02X>", c);\r
-       c_write(ldisc, cc, 4);\r
-    }\r
-}\r
-\r
-static int char_start(Ldisc ldisc, unsigned char c)\r
-{\r
-    if (in_utf(ldisc->term))\r
-       return (c < 0x80 || c >= 0xC0);\r
-    else\r
-       return 1;\r
-}\r
-\r
-static void bsb(Ldisc ldisc, int n)\r
-{\r
-    while (n--)\r
-       c_write(ldisc, "\010 \010", 3);\r
-}\r
-\r
-#define CTRL(x) (x^'@')\r
-#define KCTRL(x) ((x^'@') | 0x100)\r
-\r
-void *ldisc_create(Config *mycfg, Terminal *term,\r
-                  Backend *back, void *backhandle,\r
-                  void *frontend)\r
-{\r
-    Ldisc ldisc = snew(struct ldisc_tag);\r
-\r
-    ldisc->buf = NULL;\r
-    ldisc->buflen = 0;\r
-    ldisc->bufsiz = 0;\r
-    ldisc->quotenext = 0;\r
-\r
-    ldisc->cfg = mycfg;\r
-    ldisc->back = back;\r
-    ldisc->backhandle = backhandle;\r
-    ldisc->term = term;\r
-    ldisc->frontend = frontend;\r
-\r
-    /* Link ourselves into the backend and the terminal */\r
-    if (term)\r
-       term->ldisc = ldisc;\r
-    if (back)\r
-       back->provide_ldisc(backhandle, ldisc);\r
-\r
-    return ldisc;\r
-}\r
-\r
-void ldisc_free(void *handle)\r
-{\r
-    Ldisc ldisc = (Ldisc) handle;\r
-\r
-    if (ldisc->term)\r
-       ldisc->term->ldisc = NULL;\r
-    if (ldisc->back)\r
-       ldisc->back->provide_ldisc(ldisc->backhandle, NULL);\r
-    if (ldisc->buf)\r
-       sfree(ldisc->buf);\r
-    sfree(ldisc);\r
-}\r
-\r
-void ldisc_send(void *handle, char *buf, int len, int interactive)\r
-{\r
-    Ldisc ldisc = (Ldisc) handle;\r
-    int keyflag = 0;\r
-    /*\r
-     * Called with len=0 when the options change. We must inform\r
-     * the front end in case it needs to know.\r
-     */\r
-    if (len == 0) {\r
-       ldisc_update(ldisc->frontend, ECHOING, EDITING);\r
-       return;\r
-    }\r
-    /*\r
-     * Notify the front end that something was pressed, in case\r
-     * it's depending on finding out (e.g. keypress termination for\r
-     * Close On Exit). \r
-     */\r
-    frontend_keypress(ldisc->frontend);\r
-\r
-    /*\r
-     * Less than zero means null terminated special string.\r
-     */\r
-    if (len < 0) {\r
-       len = strlen(buf);\r
-       keyflag = KCTRL('@');\r
-    }\r
-    /*\r
-     * Either perform local editing, or just send characters.\r
-     */\r
-    if (EDITING) {\r
-       while (len--) {\r
-           int c;\r
-           c = (unsigned char)(*buf++) + keyflag;\r
-           if (!interactive && c == '\r')\r
-               c += KCTRL('@');\r
-           switch (ldisc->quotenext ? ' ' : c) {\r
-               /*\r
-                * ^h/^?: delete, and output BSBs, to return to\r
-                * last character boundary (in UTF-8 mode this may\r
-                * be more than one byte)\r
-                * ^w: delete, and output BSBs, to return to last\r
-                * space/nonspace boundary\r
-                * ^u: delete, and output BSBs, to return to BOL\r
-                * ^c: Do a ^u then send a telnet IP\r
-                * ^z: Do a ^u then send a telnet SUSP\r
-                * ^\: Do a ^u then send a telnet ABORT\r
-                * ^r: echo "^R\n" and redraw line\r
-                * ^v: quote next char\r
-                * ^d: if at BOL, end of file and close connection,\r
-                * else send line and reset to BOL\r
-                * ^m: send line-plus-\r\n and reset to BOL\r
-                */\r
-             case KCTRL('H'):\r
-             case KCTRL('?'):         /* backspace/delete */\r
-               if (ldisc->buflen > 0) {\r
-                   do {\r
-                       if (ECHOING)\r
-                           bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));\r
-                       ldisc->buflen--;\r
-                   } while (!char_start(ldisc, ldisc->buf[ldisc->buflen]));\r
-               }\r
-               break;\r
-             case CTRL('W'):          /* delete word */\r
-               while (ldisc->buflen > 0) {\r
-                   if (ECHOING)\r
-                       bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));\r
-                   ldisc->buflen--;\r
-                   if (ldisc->buflen > 0 &&\r
-                       isspace((unsigned char)ldisc->buf[ldisc->buflen-1]) &&\r
-                       !isspace((unsigned char)ldisc->buf[ldisc->buflen]))\r
-                       break;\r
-               }\r
-               break;\r
-             case CTRL('U'):          /* delete line */\r
-             case CTRL('C'):          /* Send IP */\r
-             case CTRL('\\'):         /* Quit */\r
-             case CTRL('Z'):          /* Suspend */\r
-               while (ldisc->buflen > 0) {\r
-                   if (ECHOING)\r
-                       bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));\r
-                   ldisc->buflen--;\r
-               }\r
-               ldisc->back->special(ldisc->backhandle, TS_EL);\r
-                /*\r
-                 * We don't send IP, SUSP or ABORT if the user has\r
-                 * configured telnet specials off! This breaks\r
-                 * talkers otherwise.\r
-                 */\r
-                if (!ldisc->cfg->telnet_keyboard)\r
-                    goto default_case;\r
-               if (c == CTRL('C'))\r
-                   ldisc->back->special(ldisc->backhandle, TS_IP);\r
-               if (c == CTRL('Z'))\r
-                   ldisc->back->special(ldisc->backhandle, TS_SUSP);\r
-               if (c == CTRL('\\'))\r
-                   ldisc->back->special(ldisc->backhandle, TS_ABORT);\r
-               break;\r
-             case CTRL('R'):          /* redraw line */\r
-               if (ECHOING) {\r
-                   int i;\r
-                   c_write(ldisc, "^R\r\n", 4);\r
-                   for (i = 0; i < ldisc->buflen; i++)\r
-                       pwrite(ldisc, ldisc->buf[i]);\r
-               }\r
-               break;\r
-             case CTRL('V'):          /* quote next char */\r
-               ldisc->quotenext = TRUE;\r
-               break;\r
-             case CTRL('D'):          /* logout or send */\r
-               if (ldisc->buflen == 0) {\r
-                   ldisc->back->special(ldisc->backhandle, TS_EOF);\r
-               } else {\r
-                   ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);\r
-                   ldisc->buflen = 0;\r
-               }\r
-               break;\r
-               /*\r
-                * This particularly hideous bit of code from RDB\r
-                * allows ordinary ^M^J to do the same thing as\r
-                * magic-^M when in Raw protocol. The line `case\r
-                * KCTRL('M'):' is _inside_ the if block. Thus:\r
-                * \r
-                *  - receiving regular ^M goes straight to the\r
-                *    default clause and inserts as a literal ^M.\r
-                *  - receiving regular ^J _not_ directly after a\r
-                *    literal ^M (or not in Raw protocol) fails the\r
-                *    if condition, leaps to the bottom of the if,\r
-                *    and falls through into the default clause\r
-                *    again.\r
-                *  - receiving regular ^J just after a literal ^M\r
-                *    in Raw protocol passes the if condition,\r
-                *    deletes the literal ^M, and falls through\r
-                *    into the magic-^M code\r
-                *  - receiving a magic-^M empties the line buffer,\r
-                *    signals end-of-line in one of the various\r
-                *    entertaining ways, and _doesn't_ fall out of\r
-                *    the bottom of the if and through to the\r
-                *    default clause because of the break.\r
-                */\r
-             case CTRL('J'):\r
-               if (ldisc->cfg->protocol == PROT_RAW &&\r
-                   ldisc->buflen > 0 && ldisc->buf[ldisc->buflen - 1] == '\r') {\r
-                   if (ECHOING)\r
-                       bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));\r
-                   ldisc->buflen--;\r
-                   /* FALLTHROUGH */\r
-             case KCTRL('M'):         /* send with newline */\r
-                   if (ldisc->buflen > 0)\r
-                       ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);\r
-                   if (ldisc->cfg->protocol == PROT_RAW)\r
-                       ldisc->back->send(ldisc->backhandle, "\r\n", 2);\r
-                   else if (ldisc->cfg->protocol == PROT_TELNET && ldisc->cfg->telnet_newline)\r
-                       ldisc->back->special(ldisc->backhandle, TS_EOL);\r
-                   else\r
-                       ldisc->back->send(ldisc->backhandle, "\r", 1);\r
-                   if (ECHOING)\r
-                       c_write(ldisc, "\r\n", 2);\r
-                   ldisc->buflen = 0;\r
-                   break;\r
-               }\r
-               /* FALLTHROUGH */\r
-             default:                 /* get to this label from ^V handler */\r
-                default_case:\r
-               if (ldisc->buflen >= ldisc->bufsiz) {\r
-                   ldisc->bufsiz = ldisc->buflen + 256;\r
-                   ldisc->buf = sresize(ldisc->buf, ldisc->bufsiz, char);\r
-               }\r
-               ldisc->buf[ldisc->buflen++] = c;\r
-               if (ECHOING)\r
-                   pwrite(ldisc, (unsigned char) c);\r
-               ldisc->quotenext = FALSE;\r
-               break;\r
-           }\r
-       }\r
-    } else {\r
-       if (ldisc->buflen != 0) {\r
-           ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);\r
-           while (ldisc->buflen > 0) {\r
-               bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));\r
-               ldisc->buflen--;\r
-           }\r
-       }\r
-       if (len > 0) {\r
-           if (ECHOING)\r
-               c_write(ldisc, buf, len);\r
-           if (keyflag && ldisc->cfg->protocol == PROT_TELNET && len == 1) {\r
-               switch (buf[0]) {\r
-                 case CTRL('M'):\r
-                   if (ldisc->cfg->protocol == PROT_TELNET && ldisc->cfg->telnet_newline)\r
-                       ldisc->back->special(ldisc->backhandle, TS_EOL);\r
-                   else\r
-                       ldisc->back->send(ldisc->backhandle, "\r", 1);\r
-                   break;\r
-                 case CTRL('?'):\r
-                 case CTRL('H'):\r
-                   if (ldisc->cfg->telnet_keyboard) {\r
-                       ldisc->back->special(ldisc->backhandle, TS_EC);\r
-                       break;\r
-                   }\r
-                 case CTRL('C'):\r
-                   if (ldisc->cfg->telnet_keyboard) {\r
-                       ldisc->back->special(ldisc->backhandle, TS_IP);\r
-                       break;\r
-                   }\r
-                 case CTRL('Z'):\r
-                   if (ldisc->cfg->telnet_keyboard) {\r
-                       ldisc->back->special(ldisc->backhandle, TS_SUSP);\r
-                       break;\r
-                   }\r
-\r
-                 default:\r
-                   ldisc->back->send(ldisc->backhandle, buf, len);\r
-                   break;\r
-               }\r
-           } else\r
-               ldisc->back->send(ldisc->backhandle, buf, len);\r
-       }\r
-    }\r
-}\r