home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / tn3270 / tools / prt3270.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-26  |  12.2 KB  |  621 lines

  1. /*-
  2.  * Copyright (c) 1988 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1988 The Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)prt3270.c    4.2 (Berkeley) 4/26/91";
  42. #endif /* not lint */
  43.  
  44. #if defined(unix)
  45. #endif
  46. #include <stdio.h>
  47. #include <ctype.h>
  48.  
  49. #include "../general/general.h"
  50.  
  51. #include "../api/asc_ebc.h"
  52. #include "../ctlr/hostctlr.h"
  53. #include "../ctlr/screen.h"
  54. #include "../ctlr/function.h"
  55. #include "../api/astosc.h"
  56. #include "../general/globals.h"
  57.  
  58. #include "../ctlr/kbd.out"
  59.  
  60.  
  61. int NumberColumns = 80;
  62.  
  63. int direction;
  64.  
  65. int column = 1;
  66. int indenting = 0;
  67. int direction = '?';
  68.  
  69. unsigned char printBuffer[200], *print = printBuffer;
  70.  
  71. #define    ColsLeft()    (79-column)    /* A little room for error */
  72.  
  73.  
  74. void
  75. putSpace()
  76. {
  77.     extern void Column1();
  78.     unsigned char *ourPrint = print;
  79.  
  80.     print = printBuffer;        /* For mutual calls */
  81.     *ourPrint = 0;
  82.     if (ColsLeft() < 0) {
  83.     Column1();
  84.     }
  85.     if (column != (indenting*8+1)) {
  86.     putchar(' ');
  87.     } else {
  88.     int i;
  89.  
  90.     putchar(direction);
  91.     putchar(' ');
  92.     for (i = 0; i < indenting; i++) {
  93.         putchar('\t');
  94.     }
  95.     }
  96.     printf("%s", printBuffer);
  97.     column += strlen(printBuffer);
  98. }
  99.  
  100. void
  101. Column1()
  102. {
  103.     if (print != printBuffer) {
  104.     putSpace();
  105.     }
  106.     if (column != (indenting*8+1)) {
  107.     putchar('\n');
  108.     column = indenting*8+1;
  109.     }
  110. }
  111.  
  112. void
  113. Indent()
  114. {
  115.     if ((column != (indenting*8+1)) || (print != printBuffer)) {
  116.     Column1();
  117.     }
  118.     indenting++;
  119.     column = indenting*8+1;
  120. }
  121.  
  122. void
  123. Undent()
  124. {
  125.     if ((column != (indenting*8+1)) || (print != printBuffer)) {
  126.     Column1();
  127.     }
  128.     indenting--;
  129.     if (indenting < 0) {
  130.     fflush(stdout);
  131.     fprintf(stderr, "INTERNAL ERROR: indenting < 0.\n");
  132.     fflush(stderr);
  133.     } else {
  134.     column = indenting*8+1;
  135.     }
  136. }
  137.  
  138. void
  139. putChar(character)
  140. int    character;
  141. {
  142.     *print++ = character;
  143.     column++;
  144. }
  145.  
  146. void
  147. putstr(s)
  148. char *s;
  149. {
  150.     while (*s) {
  151.     putChar(*s++);
  152.     }
  153. }
  154.  
  155. void
  156. put2hex(i)
  157. int i;
  158. {
  159.     char place[40];
  160.  
  161.     sprintf(place, "%02x", i);
  162.     putstr(place);
  163. }
  164.  
  165.  
  166. void
  167. putdecimal(i)
  168. int i;
  169. {
  170.     char place[40];
  171.  
  172.     sprintf(place, "%d", i);
  173.     putstr(place);
  174. }
  175.  
  176. void
  177. puthex(i)
  178. int i;
  179. {
  180.     char place[40];
  181.  
  182.     sprintf(place, "%x", i);
  183.     putstr(place);
  184. }
  185.  
  186. void
  187. putEChar(character)
  188. int character;
  189. {
  190.     putChar(ebc_asc[character]);
  191.     if (ColsLeft() < 10) {
  192.     Column1();
  193.     }
  194. }
  195.  
  196. void
  197. PrintAid(i)
  198. int    i;
  199. {
  200.     struct astosc *this;
  201.  
  202.     for (this = &astosc[0]; this <= &astosc[highestof(astosc)]; this++) {
  203.     if (this->function == FCN_AID) {
  204.         int j;
  205.  
  206.         switch (this->shiftstate) {
  207.         case 0:
  208.         j = 0;
  209.         break;
  210.         case SHIFT_UPSHIFT:
  211.         j = 1;
  212.         break;
  213.         case SHIFT_ALT:
  214.         j = 2;
  215.         break;
  216.         case (SHIFT_UPSHIFT|SHIFT_ALT):
  217.         j = 3;
  218.         break;
  219.         default:
  220.         fprintf(stderr, "Bad shiftstate 0x%x.\n", this->shiftstate);
  221.         exit(1);
  222.         }
  223.         if (hits[this->scancode].hit[j].code == i) {
  224.         putstr(this->name);
  225.         return;
  226.         }
  227.     }
  228.     }
  229.  
  230.     putstr("Unknown AID 0x");
  231.     put2hex(i);
  232. }
  233.  
  234. void
  235. PrintAddr(i)
  236. int    i;
  237. {
  238.     if (ColsLeft() < 9) {
  239.     Column1();
  240.     }
  241.     putChar('(');
  242.     putdecimal(ScreenLine(i));
  243.     putChar(',');
  244.     putdecimal(ScreenLineOffset(i));
  245.     putChar(')');
  246. }
  247.  
  248.  
  249. /* returns the number of characters consumed */
  250. int
  251. DataFromNetwork(buffer, count, control)
  252. register unsigned char    *buffer;        /* what the data is */
  253. register int    count;                /* and how much there is */
  254. int    control;                /* this buffer ended block? */
  255. {
  256.     int origCount;
  257.     register int c;
  258.     register int i;
  259.     static int Command;
  260.     static int Wcc;
  261.     static int    LastWasTerminated = 1;    /* was "control" = 1 last time? */
  262.  
  263.     if (count == 0) {
  264.     Column1();
  265.     return 0;
  266.     }
  267.  
  268.     origCount = count;
  269.  
  270.     if (LastWasTerminated) {
  271.  
  272.     if (count < 2) {
  273.         if (count == 0) {
  274.         fflush(stdout);
  275.         fprintf(stderr, "Short count received from host!\n");
  276.         fflush(stderr);
  277.         return(count);
  278.         }
  279.         Command = buffer[0];
  280.         switch (Command) {        /* This had better be a read command */
  281.         case CMD_READ_MODIFIED:
  282.         putstr("read_modified command\n");
  283.         break;
  284.         case CMD_SNA_READ_MODIFIED:
  285.         putstr("sna_read_modified command\n");
  286.         break;
  287.         case CMD_SNA_READ_MODIFIED_ALL:
  288.         putstr("sna_read_modified_all command\n");
  289.         break;
  290.         case CMD_READ_BUFFER:
  291.         putstr("read_buffer command\n");
  292.         break;
  293.         case CMD_SNA_READ_BUFFER:
  294.         putstr("sna_read_buffer command\n");
  295.         break;
  296.         default:
  297.         break;
  298.         }
  299.         return(1);            /* We consumed everything */
  300.     }
  301.     Command = buffer[0];
  302.     Wcc = buffer[1];
  303.     switch (Command) {
  304.     case CMD_ERASE_WRITE:
  305.         putstr("erase write command ");
  306.         break;
  307.     case CMD_ERASE_WRITE_ALTERNATE:
  308.         putstr("erase write alternate command ");
  309.         break;
  310.     case CMD_SNA_ERASE_WRITE:
  311.         putstr("sna erase write command ");
  312.         break;
  313.     case CMD_SNA_ERASE_WRITE_ALTERNATE:
  314.         putstr("erase write alternate command ");
  315.         break;
  316.     case CMD_ERASE_ALL_UNPROTECTED:
  317.         putstr("erase all unprotected command ");
  318.         break;
  319.     case CMD_SNA_ERASE_ALL_UNPROTECTED:
  320.         putstr("sna erase write command ");
  321.         break;
  322.     case CMD_WRITE:
  323.         putstr("write command ");
  324.         break;
  325.     case CMD_SNA_WRITE:
  326.         putstr("sna write command ");
  327.         break;
  328.     default:
  329.         putstr("Unexpected command code 0x");
  330.         puthex(Command);
  331.         putstr(" received.");
  332.         Column1();
  333.         break;
  334.     }
  335.     putstr("WCC is 0x");
  336.     puthex(Wcc);
  337.     Column1();
  338.  
  339.     count -= 2;            /* strip off command and wcc */
  340.     buffer += 2;
  341.  
  342.     }
  343.     LastWasTerminated = 0;        /* then, reset at end... */
  344.  
  345.     while (count) {
  346.     count--;
  347.     c = *buffer++;
  348.     if (IsOrder(c)) {
  349.         /* handle an order */
  350.         switch (c) {
  351. #        define Ensure(x)    if (count < x) { \
  352.                         if (!control) { \
  353.                         return(origCount-(count+1)); \
  354.                         } else { \
  355.                         /* XXX - should not occur */ \
  356.                         count = 0; \
  357.                         break; \
  358.                         } \
  359.                     }
  360.         case ORDER_SF:
  361.         Ensure(1);
  362.         c = *buffer++;
  363.         count--;
  364.         putstr("SF (0x");
  365.         put2hex(c);
  366.         putstr(") ");
  367.         break;
  368.         case ORDER_SBA:
  369.         Ensure(2);
  370.         i = buffer[0];
  371.         c = buffer[1];
  372.         buffer += 2;
  373.         count -= 2;
  374.         putstr("SBA to ");
  375.         PrintAddr(Addr3270(i,c));
  376.         putSpace();
  377.         break;
  378.         case ORDER_IC:
  379.         putstr("IC");
  380.         putSpace();
  381.         break;
  382.         case ORDER_PT:
  383.         putstr("PT");
  384.         putSpace();
  385.         break;
  386.         case ORDER_RA:
  387.         Ensure(3);
  388.         i = Addr3270(buffer[0], buffer[1]);
  389.         c = buffer[2];
  390.         buffer += 3;
  391.         count -= 3;
  392.         putstr("RA to ");
  393.         PrintAddr(i);
  394.         putstr(" of 0x");
  395.         put2hex(c);
  396.         putSpace();
  397.         break;
  398.         case ORDER_EUA:    /* (from [here,there), ie: half open interval] */
  399.         Ensure(2);
  400.         putstr("EUA to ");
  401.         PrintAddr(Addr3270(buffer[0], buffer[1]));
  402.         putSpace();
  403.         buffer += 2;
  404.         count -= 2;
  405.         break;
  406.         case ORDER_YALE:        /* special YALE defined order */
  407.         Ensure(2);    /* need at least two characters */
  408.         putstr("YALE order");
  409.         putSpace();
  410.         break;
  411.         default:
  412.         putstr("UNKNOWN ORDER: 0x");
  413.         put2hex(c);
  414.         putSpace();
  415.         break;
  416.         }
  417.         if (count < 0) {
  418.         count = 0;
  419.         }
  420.     } else {
  421.         /* Data comes in large clumps - take it all */
  422.         putstr("DATA:");
  423.         Indent();
  424.         putEChar(c);
  425.         c = *buffer;
  426.         while (count && !IsOrder(c)) {
  427.         putEChar(c);
  428.         count--;
  429.         buffer++;
  430.         c = *buffer;
  431.         }
  432.         Undent();
  433.     }
  434.     }
  435.     LastWasTerminated = control;
  436.     return origCount - count;
  437. }
  438.  
  439. int
  440. DataToNetwork(buffer, count, control)
  441. unsigned char *buffer;
  442. int count;
  443. int control;
  444. {
  445. #define    NEED_AID    0
  446. #define    JUST_GOT_AID    1
  447. #define    DATA        2
  448. #define    DATA_CONTINUE    3
  449.     static int state = NEED_AID;
  450.     static int aid;
  451.     int origCount = count;
  452.  
  453.     if (count == 0) {
  454.     if (control) {
  455.         state = NEED_AID;
  456.     }
  457.     Column1();
  458.     return 0;
  459.     }
  460.  
  461.     switch (state) {
  462.     case NEED_AID:
  463.     aid = buffer[0];
  464.     buffer++;
  465.     count--;
  466.     PrintAid(aid);
  467.     putSpace();
  468.     if (aid == AID_TREQ) {
  469.         state = DATA;
  470.     } else {
  471.         state = JUST_GOT_AID;
  472.     }
  473.     return origCount - count + DataToNetwork(buffer, count, control);
  474.     case JUST_GOT_AID:
  475.     Ensure(2);
  476.     PrintAddr(Addr3270(buffer[0], buffer[1]));
  477.     putSpace();
  478.     buffer += 2;
  479.     count -= 2;
  480.     state = DATA;
  481.     return origCount - count + DataToNetwork(buffer, count, control);
  482.     case DATA:
  483.     case DATA_CONTINUE:
  484.     while (count) {
  485.         if (*buffer == ORDER_SBA) {
  486.         if (state == DATA_CONTINUE) {
  487.             Undent();
  488.             state = DATA;
  489.         }
  490.         putstr("SBA ");
  491.         PrintAddr(Addr3270(buffer[1], buffer[2]));
  492.         putSpace();
  493.         buffer += 3;
  494.         count -= 3;
  495.         } else {
  496.         if (state == DATA) {
  497.             putstr("DATA:");
  498.             Indent();
  499.             state = DATA_CONTINUE;
  500.         }
  501.         putEChar(*buffer);
  502.         buffer++;
  503.         count--;
  504.         }
  505.     }
  506.     if (control) {
  507.         if (state == DATA_CONTINUE) {
  508.         Undent();
  509.         }
  510.         state = NEED_AID;
  511.     }
  512.     return origCount-count;
  513.     }
  514. }
  515.  
  516. int
  517. GetXValue(c)
  518. int    c;
  519. {
  520.     if (!isascii(c)) {
  521.     fflush(stdout);
  522.     fprintf(stderr, "Non-hex digit 0x%x.\n");
  523.     fflush(stderr);
  524.     return 0;
  525.     } else {
  526.     if (islower(c)) {
  527.         return (c-'a')+10;
  528.     } else if (isupper(c)) {
  529.         return (c-'A')+10;
  530.     } else {
  531.         return c-'0';
  532.     }
  533.     }
  534. }
  535.  
  536. unsigned char outbound[8192], inbound[8192],
  537.     *outnext = outbound, *innext = inbound, *p = 0;
  538.  
  539. void
  540. termblock(old, new, control)
  541. int old,
  542.     new;        /* old and new directions */
  543. {
  544.     int count;
  545.  
  546.     if (p) {
  547.     if (old == '<') {
  548.         outnext = p;
  549.         count = DataFromNetwork(outbound, outnext-outbound, control);
  550.         if (outbound+count == outnext) {
  551.         outnext = outbound;
  552.         } else {
  553.         memcpy(outbound, outbound+count, outnext-(outbound+count));
  554.         outnext = outbound+count;
  555.         }
  556.     } else {
  557.         innext = p;
  558.         count = DataToNetwork(inbound, innext-inbound, control);
  559.         if (inbound+count == innext) {
  560.         innext = inbound;
  561.         } else {
  562.         memcpy(inbound, inbound+count, innext-(inbound+count));
  563.         innext = inbound+count;
  564.         }
  565.     }
  566.     }
  567.     if (new == '<') {
  568.     p = outnext;
  569.     } else if (new == '>') {
  570.     p = innext;
  571.     } else {
  572.     fprintf(stderr, "Bad direction character '%c'.\n", new);
  573.     exit(1);
  574.     }
  575. }
  576.  
  577. main()
  578. {
  579.     int location;
  580.     char new;
  581.     int c, c1;
  582.  
  583.     memset(Orders, 0, sizeof Orders);
  584.     Orders[ORDER_SF] = Orders[ORDER_SBA] = Orders[ORDER_IC]
  585.         = Orders[ORDER_PT] = Orders[ORDER_RA] = Orders[ORDER_EUA]
  586.         = Orders[ORDER_YALE] = 1;
  587.  
  588.     while (scanf("%c 0x%x\t", &new, &location) != EOF) {
  589.     if (new != direction) {
  590.         termblock(direction, new, 0);
  591.         direction = new;
  592.     }
  593.     while (((c = getchar()) != EOF) && (c != '\n') && (isxdigit(c))) {
  594. #define    NORMAL    0
  595. #define    GOT0XFF    0xff
  596.         static int state = NORMAL;
  597.  
  598.         c1 = getchar();
  599.         c = (GetXValue(c) << 4) + GetXValue(c1);
  600.         switch (state) {
  601.         case NORMAL:
  602.         if (c == 0xff) {
  603.             state = GOT0XFF;
  604.         } else {
  605.             *p++ = c;
  606.         }
  607.         break;
  608.         case GOT0XFF:
  609.         if (c == 0xef) {
  610.             termblock(direction, direction, 1);
  611.         } else {
  612.             *p++ = 0xff;
  613.             *p++ = c;
  614.         }
  615.         state = NORMAL;
  616.         }
  617.     }
  618.     }
  619.     return 0;
  620. }
  621.