Several items:
[unix-history] / usr / src / usr.bin / telnet / utilities.c
index 1a5346a..d8e0d31 100644 (file)
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)utilities.c        1.13 (Berkeley) %G%";
+static char sccsid[] = "@(#)utilities.c        1.16 (Berkeley) %G%";
 #endif /* not lint */
 
 #define        TELOPTS
 #endif /* not lint */
 
 #define        TELOPTS
+#define        TELCMDS
 #include <arpa/telnet.h>
 #include <sys/types.h>
 
 #include <arpa/telnet.h>
 #include <sys/types.h>
 
@@ -36,6 +37,7 @@ static char sccsid[] = "@(#)utilities.c       1.13 (Berkeley) %G%";
 #include "externs.h"
 
 FILE   *NetTrace = 0;          /* Not in bss, since needs to stay */
 #include "externs.h"
 
 FILE   *NetTrace = 0;          /* Not in bss, since needs to stay */
+int    prettydump;
 
 /*
  * upcase()
 
 /*
  * upcase()
@@ -88,6 +90,25 @@ int
  * The following are routines used to print out debugging information.
  */
 
  * The following are routines used to print out debugging information.
  */
 
+unsigned char NetTraceFile[256] = "(standard output)";
+
+void
+SetNetTrace(file)
+register char *file;
+{
+    if (NetTrace && NetTrace != stdout)
+       fclose(NetTrace);
+    if (file  && (strcmp(file, "-") != 0)) {
+       NetTrace = fopen(file, "w");
+       if (NetTrace) {
+           strcpy(NetTraceFile, file);
+           return;
+       }
+       fprintf(stderr, "Cannot open %s.\n", file);
+    }
+    NetTrace = stdout;
+    strcpy(NetTraceFile, "(standard output)");
+}
 
 void
 Dump(direction, buffer, length)
 
 void
 Dump(direction, buffer, length)
@@ -99,6 +120,7 @@ int  length;
 #   define min(x,y)    ((x<y)? x:y)
     char *pThis;
     int offset;
 #   define min(x,y)    ((x<y)? x:y)
     char *pThis;
     int offset;
+    extern pettydump;
 
     offset = 0;
 
 
     offset = 0;
 
@@ -106,18 +128,30 @@ int       length;
        /* print one line */
        fprintf(NetTrace, "%c 0x%x\t", direction, offset);
        pThis = buffer;
        /* print one line */
        fprintf(NetTrace, "%c 0x%x\t", direction, offset);
        pThis = buffer;
-       buffer = buffer+min(length, BYTES_PER_LINE);
-       while (pThis < buffer) {
-           fprintf(NetTrace, "%.2x", (*pThis)&0xff);
-           pThis++;
+       if (prettydump) {
+           buffer = buffer + min(length, BYTES_PER_LINE/2);
+           while (pThis < buffer) {
+               fprintf(NetTrace, "%c%.2x",
+                   (((*pThis)&0xff) == 0xff) ? '*' : ' ',
+                   (*pThis)&0xff);
+               pThis++;
+           }
+           length -= BYTES_PER_LINE/2;
+           offset += BYTES_PER_LINE/2;
+       } else {
+           buffer = buffer + min(length, BYTES_PER_LINE);
+           while (pThis < buffer) {
+               fprintf(NetTrace, "%.2x", (*pThis)&0xff);
+               pThis++;
+           }
+           length -= BYTES_PER_LINE;
+           offset += BYTES_PER_LINE;
        }
        if (NetTrace == stdout) {
            fprintf(NetTrace, "\r\n");
        } else {
            fprintf(NetTrace, "\n");
        }
        }
        if (NetTrace == stdout) {
            fprintf(NetTrace, "\r\n");
        } else {
            fprintf(NetTrace, "\n");
        }
-       length -= BYTES_PER_LINE;
-       offset += BYTES_PER_LINE;
        if (length < 0) {
            fflush(NetTrace);
            return;
        if (length < 0) {
            fflush(NetTrace);
            return;
@@ -136,53 +170,401 @@ printoption(direction, fmt, option)
        if (!showoptions)
                return;
        fprintf(NetTrace, "%s ", direction);
        if (!showoptions)
                return;
        fprintf(NetTrace, "%s ", direction);
-       if (option < (sizeof telopts/sizeof telopts[0]))
-               fprintf(NetTrace, "%s %s", fmt, telopts[option]);
+       if (TELOPT_OK(option))
+               fprintf(NetTrace, "%s %s", fmt, TELOPT(option));
+       else if (TELCMD_OK(option))
+               fprintf(NetTrace, "%s %s", fmt, TELCMD(option));
        else
                fprintf(NetTrace, "%s %d", fmt, option);
        else
                fprintf(NetTrace, "%s %d", fmt, option);
-       if (NetTrace == stdout) {
+       if (NetTrace == stdout)
            fprintf(NetTrace, "\r\n");
            fprintf(NetTrace, "\r\n");
-       } else {
+       else
            fprintf(NetTrace, "\n");
            fprintf(NetTrace, "\n");
-       }
        return;
 }
 
        return;
 }
 
+optionstatus()
+{
+    register int i;
+    extern char will_wont_resp[], do_dont_resp[];
+
+    for (i = 0; i < 256; i++) {
+       if (do_dont_resp[i]) {
+           if (TELOPT_OK(i))
+               printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
+           else if (TELCMD_OK(i))
+               printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
+           else
+               printf("resp DO_DONT %d: %d\n", i,
+                               do_dont_resp[i]);
+           if (my_want_state_is_do(i)) {
+               if (TELOPT_OK(i))
+                   printf("want DO   %s\n", TELOPT(i));
+               else if (TELCMD_OK(i))
+                   printf("want DO   %s\n", TELCMD(i));
+               else
+                   printf("want DO   %d\n", i);
+           } else {
+               if (TELOPT_OK(i))
+                   printf("want DONT %s\n", TELOPT(i));
+               else if (TELCMD_OK(i))
+                   printf("want DONT %s\n", TELCMD(i));
+               else
+                   printf("want DONT %d\n", i);
+           }
+       } else {
+           if (my_state_is_do(i)) {
+               if (TELOPT_OK(i))
+                   printf("     DO   %s\n", TELOPT(i));
+               else if (TELCMD_OK(i))
+                   printf("     DO   %s\n", TELCMD(i));
+               else
+                   printf("     DO   %d\n", i);
+           }
+       }
+       if (will_wont_resp[i]) {
+           if (TELOPT_OK(i))
+               printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
+           else if (TELCMD_OK(i))
+               printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
+           else
+               printf("resp WILL_WONT %d: %d\n",
+                               i, will_wont_resp[i]);
+           if (my_want_state_is_will(i)) {
+               if (TELOPT_OK(i))
+                   printf("want WILL %s\n", TELOPT(i));
+               else if (TELCMD_OK(i))
+                   printf("want WILL %s\n", TELCMD(i));
+               else
+                   printf("want WILL %d\n", i);
+           } else {
+               if (TELOPT_OK(i))
+                   printf("want WONT %s\n", TELOPT(i));
+               else if (TELCMD_OK(i))
+                   printf("want WONT %s\n", TELCMD(i));
+               else
+                   printf("want WONT %d\n", i);
+           }
+       } else {
+           if (my_state_is_will(i)) {
+               if (TELOPT_OK(i))
+                   printf("     WILL %s\n", TELOPT(i));
+               else if (TELCMD_OK(i))
+                   printf("     WILL %s\n", TELCMD(i));
+               else
+                   printf("     WILL %d\n", i);
+           }
+       }
+    }
+
+}
+
+char *slcnames[] = { SLC_NAMES };
+
 void
 printsub(direction, pointer, length)
 void
 printsub(direction, pointer, length)
-char   *direction,             /* "<" or ">" */
-       *pointer;               /* where suboption data sits */
+char   direction;              /* '<' or '>' */
+unsigned char  *pointer;       /* where suboption data sits */
 int    length;                 /* length of suboption data */
 {
 int    length;                 /* length of suboption data */
 {
+    register int i;
+
     if (showoptions) {
     if (showoptions) {
-       fprintf(NetTrace, "%s suboption ",
-                               (direction[0] == '<')? "Received":"Sent");
+       if (direction) {
+           fprintf(NetTrace, "%s suboption ",
+                               (direction == '<')? "Received":"Sent");
+           if (length >= 3) {
+               register int j;
+
+               i = pointer[length-2];
+               j = pointer[length-1];
+
+               if (i != IAC || j != SE) {
+                   fprintf(NetTrace, "(terminated by ");
+                   if (TELOPT_OK(i))
+                       fprintf(NetTrace, "%s ", TELOPT(i));
+                   else if (TELCMD_OK(i))
+                       fprintf(NetTrace, "%s ", TELCMD(i));
+                   else
+                       fprintf(NetTrace, "%d ", i);
+                   if (TELOPT_OK(j))
+                       fprintf(NetTrace, "%s", TELOPT(j));
+                   else if (TELCMD_OK(j))
+                       fprintf(NetTrace, "%s", TELCMD(j));
+                   else
+                       fprintf(NetTrace, "%d", j);
+                   fprintf(NetTrace, ", not IAC SE!) ");
+               }
+           }
+           length -= 2;
+       }
+       if (length < 1) {
+           fprintf(NetTrace, "(Empty suboption???)");
+           return;
+       }
        switch (pointer[0]) {
        case TELOPT_TTYPE:
        switch (pointer[0]) {
        case TELOPT_TTYPE:
-           fprintf(NetTrace, "Terminal type ");
+           fprintf(NetTrace, "TERMINAL-TYPE ");
            switch (pointer[1]) {
            case TELQUAL_IS:
            switch (pointer[1]) {
            case TELQUAL_IS:
-               {
-                   char tmpbuf[SUBBUFSIZE];
-                   int minlen = min(length, sizeof tmpbuf);
-
-                   memcpy(tmpbuf, pointer+2, minlen);
-                   tmpbuf[minlen-1] = 0;
-                   fprintf(NetTrace, "is %s.\n", tmpbuf);
-               }
+               fprintf(NetTrace, "IS \"%.*s\"", length-2, pointer+2);
                break;
            case TELQUAL_SEND:
                break;
            case TELQUAL_SEND:
-               fprintf(NetTrace, "- request to send.\n");
+               fprintf(NetTrace, "SEND");
                break;
            default:
                fprintf(NetTrace,
                break;
            default:
                fprintf(NetTrace,
-                               "- unknown qualifier %d (0x%x).\n",
+                               "- unknown qualifier %d (0x%x).",
                                pointer[1], pointer[1]);
            }
            break;
                                pointer[1], pointer[1]);
            }
            break;
+       case TELOPT_TSPEED:
+           fprintf(NetTrace, "TERMINAL-SPEED");
+           if (length < 2) {
+               fprintf(NetTrace, " (empty suboption???)");
+               break;
+           }
+           switch (pointer[1]) {
+           case TELQUAL_IS:
+               fprintf(NetTrace, " IS ");
+               fprintf(NetTrace, "%.*s", length-2, pointer+2);
+               break;
+           default:
+               if (pointer[1] == 1)
+                   fprintf(NetTrace, " SEND");
+               else
+                   fprintf(NetTrace, " %d (unknown)");
+               for (i = 2; i < length; i++)
+                   fprintf(NetTrace, " ?%d?", pointer[i]);
+               break;
+           }
+           break;
+
+       case TELOPT_LFLOW:
+           fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
+           if (length < 2) {
+               fprintf(NetTrace, " (empty suboption???)");
+               break;
+           }
+           switch (pointer[1]) {
+           case 0:
+               fprintf(NetTrace, " OFF"); break;
+           case 1:
+               fprintf(NetTrace, " ON"); break;
+           default:
+               fprintf(NetTrace, " %d (unknown)");
+           }
+           for (i = 2; i < length; i++)
+               fprintf(NetTrace, " ?%d?", pointer[i]);
+           break;
+
+       case TELOPT_NAWS:
+           fprintf(NetTrace, "NAWS");
+           if (length < 2) {
+               fprintf(NetTrace, " (empty suboption???)");
+               break;
+           }
+           if (length == 2) {
+               fprintf(NetTrace, " ?%d?", pointer[1]);
+               break;
+           }
+           fprintf(NetTrace, " %d %d (%d)",
+               pointer[1], pointer[2],
+               (((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2]));
+           if (length == 4) {
+               fprintf(NetTrace, " ?%d?", pointer[3]);
+               break;
+           }
+           fprintf(NetTrace, " %d %d (%d)",
+               pointer[3], pointer[4],
+               (((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4]));
+           for (i = 5; i < length; i++)
+               fprintf(NetTrace, " ?%d?", pointer[i]);
+           break;
+
+       case TELOPT_LINEMODE:
+           fprintf(NetTrace, "LINEMODE ");
+           if (length < 2) {
+               fprintf(NetTrace, " (empty suboption???)");
+               break;
+           }
+           switch (pointer[1]) {
+           case WILL:
+               fprintf(NetTrace, "WILL ");
+               goto common;
+           case WONT:
+               fprintf(NetTrace, "WONT ");
+               goto common;
+           case DO:
+               fprintf(NetTrace, "DO ");
+               goto common;
+           case DONT:
+               fprintf(NetTrace, "DONT ");
+           common:
+               if (length < 3) {
+                   fprintf(NetTrace, "(no option???)");
+                   break;
+               }
+               switch (pointer[2]) {
+               case LM_FORWARDMASK:
+                   fprintf(NetTrace, "Forward Mask");
+                   for (i = 3; i < length; i++)
+                       fprintf(NetTrace, " %x", pointer[i]);
+                   break;
+               default:
+                   fprintf(NetTrace, "%d (unknown)", pointer[2]);
+                   for (i = 3; i < length; i++)
+                       fprintf(NetTrace, " %d", pointer[i]);
+                   break;
+               }
+               break;
+               
+           case LM_SLC:
+               fprintf(NetTrace, "SLC");
+               for (i = 2; i < length - 2; i += 3) {
+                   if (pointer[i+SLC_FUNC] <= NSLC)
+                       fprintf(NetTrace, " %s", slcnames[pointer[i+SLC_FUNC]]);
+                   else
+                       fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
+                   switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
+                   case SLC_NOSUPPORT:
+                       fprintf(NetTrace, " NOSUPPORT"); break;
+                   case SLC_CANTCHANGE:
+                       fprintf(NetTrace, " CANTCHANGE"); break;
+                   case SLC_VARIABLE:
+                       fprintf(NetTrace, " VARIABLE"); break;
+                   case SLC_DEFAULT:
+                       fprintf(NetTrace, " DEFAULT"); break;
+                   }
+                   fprintf(NetTrace, "%s%s%s",
+                       pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
+                       pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
+                       pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
+                   if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
+                                               SLC_FLUSHOUT| SLC_LEVELBITS))
+                       fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
+                   fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
+               }
+               for (; i < length; i++)
+                   fprintf(NetTrace, " ?%d?", pointer[i]);
+               break;
+
+           case LM_MODE:
+               fprintf(NetTrace, "MODE ");
+               if (length < 3) {
+                   fprintf(NetTrace, "(no mode???)");
+                   break;
+               }
+               {
+                   char tbuf[32];
+                   sprintf(tbuf, "%s%s%s",
+                       pointer[2]&MODE_EDIT ? "|EDIT" : "",
+                       pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
+                       pointer[2]&MODE_ACK ? "|ACK" : "");
+                   fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
+               }
+               if (pointer[2]&~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK))
+                   fprintf(NetTrace, " (0x%x)", pointer[2]);
+               for (i = 3; i < length; i++)
+                   fprintf(NetTrace, " ?0x%x?", pointer[i]);
+               break;
+           default:
+               fprintf(NetTrace, "%d (unknown)", pointer[1]);
+               for (i = 2; i < length; i++)
+                   fprintf(NetTrace, " %d", pointer[i]);
+           }
+           break;
+
+       case TELOPT_STATUS: {
+           register char *cp;
+           register int j, k;
+
+           fprintf(NetTrace, "STATUS");
+
+           switch (pointer[1]) {
+           default:
+               if (pointer[1] == TELQUAL_SEND)
+                   fprintf(NetTrace, " SEND");
+               else
+                   fprintf(NetTrace, " %d (unknown)");
+               for (i = 2; i < length; i++)
+                   fprintf(NetTrace, " ?%d?", pointer[i]);
+               break;
+           case TELQUAL_IS:
+               if (NetTrace == stdout)
+                   fprintf(NetTrace, " IS\r\n");
+               else
+                   fprintf(NetTrace, " IS\n");
+
+               for (i = 2; i < length; i++) {
+                   switch(pointer[i]) {
+                   case DO:    cp = "DO"; goto common2;
+                   case DONT:  cp = "DONT"; goto common2;
+                   case WILL:  cp = "WILL"; goto common2;
+                   case WONT:  cp = "WONT"; goto common2;
+                   common2:
+                       i++;
+                       if (TELOPT_OK(pointer[i]))
+                           fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
+                       else
+                           fprintf(NetTrace, " %s %d", cp, pointer[i]);
+
+                       if (NetTrace == stdout)
+                           fprintf(NetTrace, "\r\n");
+                       else
+                           fprintf(NetTrace, "\n");
+                       break;
+
+                   case SB:
+                       fprintf(NetTrace, " SB ");
+                       i++;
+                       j = k = i;
+                       while (j < length) {
+                           if (pointer[j] == SE) {
+                               if (j+1 == length)
+                                   break;
+                               if (pointer[j+1] == SE)
+                                   j++;
+                               else
+                                   break;
+                           }
+                           pointer[k++] = pointer[j++];
+                       }
+                       printsub(0, &pointer[i], k - i);
+                       if (i < length) {
+                           fprintf(NetTrace, " SE");
+                           i = j;
+                       } else
+                           i = j - 1;
+
+                       if (NetTrace == stdout)
+                           fprintf(NetTrace, "\r\n");
+                       else
+                           fprintf(NetTrace, "\n");
+
+                       break;
+                               
+                   default:
+                       fprintf(NetTrace, " %d", pointer[i]);
+                       break;
+                   }
+               }
+               break;
+           }
+           break;
+         }
+
        default:
        default:
-           fprintf(NetTrace, "Unknown option %d (0x%x)\n",
-                                       pointer[0], pointer[0]);
+           fprintf(NetTrace, "Unknown option ");
+           for (i = 0; i < length; i++)
+               fprintf(NetTrace, " %d", pointer[i]);
+           break;
+       }
+       if (direction) {
+           if (NetTrace == stdout)
+               fprintf(NetTrace, "\r\n");
+           else
+               fprintf(NetTrace, "\n");
        }
     }
 }
        }
     }
 }
@@ -222,7 +604,7 @@ EmptyTerminal()
 void
 SetForExit()
 {
 void
 SetForExit()
 {
-    setconnmode();
+    setconnmode(0);
 #if    defined(TN3270)
     if (In3270) {
        Finish3270();
 #if    defined(TN3270)
     if (In3270) {
        Finish3270();
@@ -241,7 +623,7 @@ SetForExit()
        StopScreen(1);
     }
 #endif /* defined(TN3270) */
        StopScreen(1);
     }
 #endif /* defined(TN3270) */
-    setconnmode();
+    setconnmode(0);
     EmptyTerminal();                   /* Flush the path to the tty */
     setcommandmode();
 }
     EmptyTerminal();                   /* Flush the path to the tty */
     setcommandmode();
 }
@@ -263,15 +645,3 @@ int returnCode;
     fwrite(string, 1, strlen(string), stderr);
     exit(returnCode);
 }
     fwrite(string, 1, strlen(string), stderr);
     exit(returnCode);
 }
-
-#if defined(MSDOS)
-void
-ExitPerror(string, returnCode)
-char *string;
-int returnCode;
-{
-    SetForExit();
-    perror(string);
-    exit(returnCode);
-}
-#endif /* defined(MSDOS) */