RUI3270.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:72k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*****************************************************************************/
  2. /* RUI Sample Program                                                        */
  3. /*                                                                           */
  4. /* (C) Copyright 1990 - 1993 Data Connection Ltd.                            */
  5. /*                                                                           */
  6. /* This program is a crude 3270 emulator.  It uses the RUI API to access     */
  7. /* both the SSCP and LU sessions.  Outbound data from the host is            */
  8. /* displayed on the screen unformatted.  Both SSCP and LU data are shown.    */
  9. /* If the outbound data is an RQD request an automatic positive response     */
  10. /* is sent.  Inbound data can be entered at the keyboard and is sent on      */
  11. /* the current session.  This current session can be toggled between the     */
  12. /* SSCP and LU sessions by hitting the [ (left square bracket) key           */
  13. /* followed by <cr> (carriage return), although it switches                  */
  14. /* automatically on receipt of BIND or UNBIND.                               */
  15. /*                                                                           */
  16. /* The program is invoked with a single parameter - the name of the LUA LU   */
  17. /* to use.  This is converted to upper case and must match an LUA LU in      */
  18. /* the configuration file.  This LU should be configured for a 327? on the   */
  19. /* host.                                                                     */
  20. /*                                                                           */
  21. /* It works reasonably well with TSO provided that complex formatted         */
  22. /* logon screens are not used.                                               */
  23. /*                                                                           */
  24. /* To exit the program type ] (right square bracket)                         */
  25. /*                                                                           */
  26. /* The CSV CONVERT function is used to convert data between ASCII and        */
  27. /* EBCDIC.  This uses the type G conversion table, so the environment        */
  28. /* variable COMTBLG must be set to point to a suitable file.                 */
  29. /*                                                                           */
  30. /* Keys that work are:                                                       */
  31. /*                                                                           */
  32. /*     Alt-1 to Alt-0 are PF1 to PF0                                         */
  33. /*     F2 sends a CLEAR to the host                                          */
  34. /*     backspace                                                             */
  35. /*     Letters, numbers and symbols                                          */
  36. /*                                                                           */
  37. /*****************************************************************************/
  38. #ifdef WIN32
  39.   #include <windows.h>
  40. #else
  41. #ifdef DOS5
  42.   #define INCL_DOS
  43.   #define INCL_DOSERRORS
  44.   #include <os2.h>
  45. #else
  46. #define FAR far
  47. typedef unsigned int   BOOL;
  48. typedef int            INT;
  49. typedef unsigned int   UINT;
  50. typedef unsigned long  ULONG;
  51. typedef long           LONG;
  52. typedef unsigned char  UCHAR;
  53. typedef unsigned short USHORT;
  54. #define TRUE    1
  55. #define FALSE   0
  56. #define kbhit   _kbhit
  57. #define getch   _getche
  58. #endif
  59. #endif
  60. #include <stdio.h>
  61. #include <string.h>
  62. #include <stdlib.h>
  63. #include <conio.h>
  64. #include <lua_c.h>
  65. #include <acssvcc.h>
  66. /*****************************************************************************/
  67. /* Program constants                                                         */
  68. /*****************************************************************************/
  69. #define DATASIZE 4096                  /* Max size of RU                     */
  70. #define SWITKEY  0x5B                  /* '['   to switch sessions           */
  71. #define EXITKEY  0x5D                  /* ']'   to exit program              */
  72. #define BETB     1                     /* Between brackets                   */
  73. #define SEND     2                     /* In bracket and can send            */
  74. #define RECV     3                     /* In bracket, but cannot send        */
  75. /*****************************************************************************/
  76. /* State variables                                                           */
  77. /*                                                                           */
  78. /* We can only have one read or write verb outstanding per flow.  These      */
  79. /* state variables keep track of these verbs and what we need to do with     */
  80. /* them.                                                                     */
  81. /*****************************************************************************/
  82. UINT  write_state;
  83. #define NO_WRITE              1
  84. #define WRITE_OUTSTANDING     2        /* waiting for write to complete      */
  85. #define WRITE_QUEUED          3        /* have data to write                 */
  86. UINT  read_state;
  87. #define NO_READ               1
  88. #define READ_OUTSTANDING      2        /* read verb outstanding              */
  89. #define RSP_QUEUED            3        /* have a response to write           */
  90. #define RSP_OUTSTANDING       4        /* waiting for a response to complete */
  91. UINT  rpq_state;
  92. #define NO_RPQ                1
  93. #define RPQ_OUTSTANDING       2        /* waiting for an RPQ to complete     */
  94. #define RPQ_QUEUED            3        /* have RPQ to send                   */
  95. /***************************************************************************/
  96. /* Global variables                                                        */
  97. /*                                                                         */
  98. /* Inbound data is sent as typed on the SSCP session.  On the LU session   */
  99. /* it is prefixed with the <enter> key AID plus a two byte cursor address. */
  100. /***************************************************************************/
  101. LUA_VERB_RECORD read_verb;             /* RUI read verb                    */
  102. LUA_VERB_RECORD other_verb;            /* RUI init, write or term verb     */
  103. LUA_VERB_RECORD rpq_verb;              /* RUI_WRITE for RPQs               */
  104. UCHAR rpq_data[] = {
  105.   0x88,
  106.   0x00, 0x0C, 0x81, 0x80, 0x80, 0x81, 0x85, 0x86, 0x87, 0x88, 0x95, 0xA6,
  107.   0x00, 0x17, 0x81, 0x81, 0x21, 0x00, 0x00, 0x50, 0x00, 0x18, 0x00, 0x00,
  108.   0x0A, 0x02, 0xE5, 0x00, 0x02, 0x00, 0x6F, 0x09, 0x10, 0x07, 0x80,
  109.   0x00, 0x14, 0x81, 0x85, 0x02, 0x00, 0x09, 0x0E, 0x00, 0x00, 0x00, 0x00,
  110.   0x07, 0x00, 0x00, 0x00, 0x02, 0xB9, 0x01, 0x1D,
  111.   0x00, 0x16, 0x81, 0x86, 0x00, 0x08, 0x00, 0xF4, 0xF1, 0x00, 0xF2, 0x00,
  112.   0xF3, 0x00, 0xF4, 0x00, 0xF5, 0x00, 0xF6, 0x00, 0xF7, 0x00,
  113.   0x00, 0x0D, 0x81, 0x87, 0x04, 0x00, 0xF0, 0xF1, 0x00, 0xF2, 0x00, 0xF4,
  114.   0x00,
  115.   0x00, 0x07, 0x81, 0x88, 0x00, 0x01, 0x02,
  116.   0x00, 0x0C, 0x81, 0x95, 0x00, 0x00, 0x7F, 0xFF, 0x7F, 0xFF, 0x01, 0x01,
  117.   0x00, 0x11, 0x81, 0xA6, 0x00, 0x00, 0x0B, 0x01, 0x00, 0x00, 0x50, 0x00,
  118.   0x18, 0x00, 0x50, 0x00, 0x18};
  119. #define RPQ_LENGTH (sizeof(rpq_data))
  120. unsigned char read_data[DATASIZE];     /* Outbound RU                       */
  121. #define WRITE_EXTRA 6
  122. unsigned char write_array[DATASIZE + WRITE_EXTRA] =
  123.                                           {0x7d, 0x40, 0x40, 0x11, 0x40, 0x40};
  124.                                        /* Inbound RU                         */
  125. unsigned char *write_data = write_array + WRITE_EXTRA;
  126.                                        /* Pointer to inbound RU              */
  127. UINT data_offset = 0;                  /* offset into read_data              */
  128. UINT write_len   = 0;                  /* length of write data               */
  129. struct convert convert_to_asc;         /* Outbound convert verb              */
  130. struct convert convert_to_ebc;         /* Inbound convert verb               */
  131. #ifdef WIN32
  132.   HANDLE write_event = 0l;             /* write arm verb semaphore           */
  133.   HANDLE read_event  = 0l;             /* read arm verb semaphore            */
  134.   HANDLE init_event  = 0l;             /* RUI_INIT semaphore                 */
  135.   HANDLE term_event  = 0l;             /* RUI_TERM semaphore                 */
  136.   HANDLE rpq_event   = 0l;
  137.   HANDLE status_event = 0l;            /* RUI status event                   */
  138.   HANDLE std_input;                    /* standard input handle              */
  139.   HANDLE std_output;                   /* standard output handle             */
  140. #else
  141.   ULONG write_sema4 = 0l;              /* write arm verb semaphore           */
  142.   ULONG read_sema4  = 0l;              /* read arm verb semaphore            */
  143.   ULONG init_sema4  = 0l;              /* RUI_INIT semaphore                 */
  144.   ULONG term_sema4  = 0l;              /* RUI_TERM semaphore                 */
  145.   ULONG rpq_sema4   = 0l;
  146. #endif
  147. BOOL terminating = FALSE;              /* are we already in closedown() ?    */
  148. BOOL lu_session  = FALSE;              /* LU session inbound flag            */
  149. unsigned long sense = 0l;              /* sense code                         */
  150. unsigned char lu_name[9] = "        "; /* LU name                            */
  151. unsigned long sid;                     /* RUI session ID                     */
  152. int send_state = BETB;                 /* LU session send state              */
  153. #ifdef WIN32
  154.   #define INITPOST         (ULONG) init_event
  155.   #define TERMPOST         (ULONG) term_event
  156.   #define READPOST         (ULONG) read_event
  157.   #define WRITEPOST        (ULONG) write_event
  158.   #define RPQPOST          (ULONG) rpq_event
  159. #else
  160.   #define INITPOST         (unsigned long) ((UCHAR FAR *) &init_sema4)
  161.   #define TERMPOST         (unsigned long) ((UCHAR FAR *) &term_sema4)
  162.   #define READPOST         (unsigned long) ((UCHAR FAR *) &read_sema4)
  163.   #define WRITEPOST        (unsigned long) ((UCHAR FAR *) &write_sema4)
  164.   #define RPQPOST          (unsigned long) ((UCHAR FAR *) &rpq_sema4)
  165. #endif
  166. /*****************************************************************************/
  167. /* Function declarations.                                                    */
  168. /*****************************************************************************/
  169. #ifdef WIN32
  170.   #define LOADDS
  171. #else
  172.   #define LOADDS _loadds
  173. #endif
  174. void pascal far LOADDS RUI (LUA_VERB_RECORD FAR *);
  175. void            csv_init            (void);
  176. int             issue_verb          (unsigned int  type);
  177. void            issue_read          (void);
  178. void            other_done          (LUA_VERB_RECORD *verb);
  179. void            read_done           (LUA_VERB_RECORD *verb);
  180. void            issue_rsp           (unsigned long  sense);
  181. void            rsp_done            (LUA_VERB_RECORD *verb);
  182. void            closedown           (void);
  183. BOOL            do_write            (void);
  184. void            wait_verb_complete  (LUA_VERB_RECORD *verb);
  185. void            wait_active_status  (LUA_VERB_RECORD *verb);
  186. void            set_semaphore       (LUA_VERB_RECORD *verb);
  187. BOOL            do_keyboard_stuff   (void);
  188. BOOL            check_verb_complete (LUA_VERB_RECORD *verb);
  189. void            parse_data          (UCHAR FAR *, USHORT);
  190. BOOL            issue_rpq           (void);
  191. #ifdef WIN32
  192. extern int      WINAPI GetFmiReturnCode(unsigned short, unsigned short, unsigned short, unsigned char FAR *);
  193. #endif
  194. /**PROC+**********************************************************************/
  195. /* Name:      main                                                           */
  196. /*                                                                           */
  197. /* Purpose:   set up CSV convert verbs                                       */
  198. /*                                                                           */
  199. /* Returns:   none                                                           */
  200. /*                                                                           */
  201. /* Params:    argv, argc                                                     */
  202. /*                                                                           */
  203. /* Operation: Get LU name from command line                                  */
  204. /*            do some initialisation                                         */
  205. /*            Issue RUI_INIT to get LU-SSCP session                          */
  206. /*            Loop reading data from keyboard and host, and send keyboard    */
  207. /*            data to host                                                   */
  208. /**PROC-**********************************************************************/
  209. #ifdef DOS5
  210. int main(int argc, char *argv[])
  211. #else
  212. #ifdef PDOS
  213. int _cdecl main(int argc, char *argv[])
  214. #else
  215. int _CRTAPI1 main(int argc, char *argv[])
  216. #endif
  217. #endif
  218. {
  219.   BOOL whole_data;       /* we have a whole data string to write             */
  220.   BOOL verb_complete;    /* Has a verb completed                             */
  221.   BOOL write_ok;         /* Has write worked?                                */
  222.   BOOL rpq_ok;           /* Has rpq worked                                   */
  223.   int ii;
  224. #ifdef WIN32
  225.   HANDLE handle_list [6];
  226. #endif
  227. #ifdef DOS5
  228.   DEFINEMUXSEMLIST(sem_list,5)
  229.   USHORT           sem_index;
  230. #endif
  231.   printf("RUI simple 3270 applicationn");
  232.   /***************************************************************************/
  233.   /* Validate parameter usage and get LU name.                               */
  234.   /***************************************************************************/
  235.   if (argc != 2)
  236.   {
  237.     printf("Usage: RUI3270 lunamen");
  238.     exit(1);
  239.   }
  240.   if (strlen(argv[1]) > 8)
  241.   {
  242.     printf("LU name too longn");
  243.     exit(1);
  244.   }
  245.   /***************************************************************************/
  246.   /* Convert to upper case                                                   */
  247.   /***************************************************************************/
  248.   ii=0;
  249.   while (argv[1][ii])
  250.   {
  251.     if (argv[1][ii] >= 'a' && argv[1][ii] <= 'z')
  252.     {
  253.       argv[1][ii] = argv[1][ii] - 'a' + 'A';
  254.     }
  255.     ii++;
  256.   }
  257.   memcpy(lu_name, argv[1], strlen(argv[1]));
  258.   printf("lu_name %sn", lu_name);
  259.   /***************************************************************************/
  260.   /* Set up CSV convert verbs                                                */
  261.   /***************************************************************************/
  262.   csv_init();
  263. #ifdef WIN32
  264.   /***************************************************************************/
  265.   /* Create the necessary events                                             */
  266.   /***************************************************************************/
  267.   write_event  = CreateEvent (NULL, TRUE, FALSE, NULL);
  268.   read_event   = CreateEvent (NULL, TRUE, FALSE, NULL);
  269.   init_event   = CreateEvent (NULL, TRUE, FALSE, NULL);
  270.   term_event   = CreateEvent (NULL, TRUE, FALSE, NULL);
  271.   rpq_event    = CreateEvent (NULL, TRUE, FALSE, NULL);
  272.   status_event = CreateEvent (NULL,FALSE, FALSE, NULL);
  273.   /***************************************************************************/
  274.   /* Get standard input and output handles.                                  */
  275.   /***************************************************************************/
  276.   std_input  = GetStdHandle (STD_INPUT_HANDLE );
  277.   std_output = GetStdHandle (STD_OUTPUT_HANDLE);
  278.   if ((std_input  == INVALID_HANDLE_VALUE) ||
  279.       (std_output == INVALID_HANDLE_VALUE))
  280.   {
  281.     printf("GetStdHandle Failed, %d", GetLastError());
  282.     exit (1);
  283.   }
  284.   /***************************************************************************/
  285.   /* Set up list of handles to wait for                                      */
  286.   /***************************************************************************/
  287.   handle_list[0] = write_event;
  288.   handle_list[1] = read_event;
  289.   handle_list[2] = init_event;
  290.   handle_list[3] = term_event;
  291.   handle_list[4] = rpq_event;
  292.   handle_list[5] = std_input;
  293. #endif
  294. #ifdef DOS5
  295.   /***************************************************************************/
  296.   /* Set semaphores to begin with                                            */
  297.   /***************************************************************************/
  298.   DosSemSet (&init_sema4);
  299.   DosSemSet (&term_sema4);
  300.   DosSemSet (&read_sema4);
  301.   DosSemSet (&write_sema4);
  302.   DosSemSet (&rpq_sema4);
  303.   sem_list.amxs[0].hsem = &init_sema4;
  304.   sem_list.amxs[1].hsem = &term_sema4;
  305.   sem_list.amxs[2].hsem = &read_sema4;
  306.   sem_list.amxs[3].hsem = &write_sema4;
  307.   sem_list.amxs[4].hsem = &rpq_sema4;
  308. #endif
  309.   /***************************************************************************/
  310.   /* Initialize RUI and wait for ACTLU fom host.                             */
  311.   /***************************************************************************/
  312.   if (issue_verb((unsigned int) LUA_OPCODE_RUI_INIT))
  313.   {
  314.     printf("Init failedn");
  315.     exit(1);
  316.   }
  317.   /***************************************************************************/
  318.   /* Set initial states                                                      */
  319.   /***************************************************************************/
  320.   write_state = NO_WRITE;
  321.   read_state  = NO_READ;
  322.   rpq_state   = NO_RPQ;
  323.   /***************************************************************************/
  324.   /* Loop reading inbound data from the keyboard                             */
  325.   /***************************************************************************/
  326.   while (!terminating)
  327.   {
  328. #ifndef PDOS
  329.     /*************************************************************************/
  330.     /* Determine if we can pause                                             */
  331.     /*************************************************************************/
  332.     if (  (read_state != NO_READ)   &&
  333.           ((write_state != WRITE_QUEUED)    ||
  334.            (rpq_state   != NO_RPQ)          ||
  335.            (read_state  == RSP_OUTSTANDING) ||
  336.            (read_state  == RSP_QUEUED)) &&
  337.           ((rpq_state   != RPQ_QUEUED)        ||
  338.            (write_state == WRITE_OUTSTANDING) ||
  339.            (read_state  == RSP_OUTSTANDING)   ||
  340.            (read_state  == RSP_QUEUED))    &&
  341.           ((read_state != RSP_QUEUED) ||
  342.            (write_state == WRITE_OUTSTANDING)))
  343.     {
  344. #ifdef WIN32
  345.       WaitForMultipleObjects (6, handle_list, FALSE, INFINITE);
  346. #else
  347.       if (!kbhit())
  348.       {
  349.         DosMuxSemWait (&sem_index, &sem_list, 200l);
  350.       }
  351. #endif
  352.     }
  353. #endif
  354.     /*************************************************************************/
  355.     /* First check on the state of write verbs                               */
  356.     /*************************************************************************/
  357.     if ((write_state == NO_WRITE)        &&
  358.         (rpq_state   == NO_RPQ)          &&
  359.         (read_state  != RSP_QUEUED)      &&
  360.         (read_state  != RSP_OUTSTANDING))
  361.     {
  362.       /***********************************************************************/
  363.       /* Don't write here if we need to respond, since we can only have one  */
  364.       /* write outstanding on each flow.                                     */
  365.       /* Here we want to check if we have a whole string of data (i.e.  that */
  366.       /* the user has hit enter).  If so write the data to the HOST          */
  367.       /***********************************************************************/
  368.       whole_data = do_keyboard_stuff ();
  369.       if (whole_data)
  370.       {
  371.         /*********************************************************************/
  372.         /* Attempt to write the data.  May not work because of bracket state */
  373.         /*********************************************************************/
  374.         write_ok = do_write ();
  375.         if (write_ok)
  376.         {
  377.           /*******************************************************************/
  378.           /* If verb completes async change state to indicate this o.w.      */
  379.           /* call the verb done processor                                    */
  380.           /*******************************************************************/
  381.           if (other_verb.common.lua_flag2.async)
  382.           {
  383.             write_state = WRITE_OUTSTANDING;
  384.           }
  385.           else
  386.           {
  387.             other_done (&other_verb);
  388.             write_state = NO_WRITE;
  389.           }
  390.         }
  391.         else
  392.         {
  393.           /*******************************************************************/
  394.           /* Failed to do a write.  Queue up data                            */
  395.           /*******************************************************************/
  396.           write_state = WRITE_QUEUED;
  397.         }
  398.       }
  399.     }
  400.     else if ((write_state == WRITE_QUEUED)    &&
  401.              (rpq_state   == NO_RPQ)          &&
  402.              (read_state  != RSP_OUTSTANDING) &&
  403.              (read_state  != RSP_QUEUED))
  404.     {
  405.       /***********************************************************************/
  406.       /* Attempt to write the data.  May not work because of bracket state   */
  407.       /***********************************************************************/
  408.       write_ok = do_write ();
  409.       if (write_ok)
  410.       {
  411.         /*********************************************************************/
  412.         /* If verb completes async change state to indicate this o.w.  call  */
  413.         /* the verb done processor                                           */
  414.         /*********************************************************************/
  415.         if (other_verb.common.lua_flag2.async)
  416.         {
  417.           write_state = WRITE_OUTSTANDING;
  418.         }
  419.         else
  420.         {
  421.           other_done (&other_verb);
  422.           write_state = NO_WRITE;
  423.         }
  424.       }
  425.     }
  426.     else if (write_state == WRITE_OUTSTANDING)
  427.     {
  428.       /***********************************************************************/
  429.       /* We have a RUI_WRITE outstanding so check if it is complete          */
  430.       /***********************************************************************/
  431.       verb_complete = check_verb_complete (&other_verb);
  432.       if (verb_complete)
  433.       {
  434.         other_done (&other_verb);
  435.         write_state = NO_WRITE;
  436.       }
  437.     }
  438.     /*************************************************************************/
  439.     /* Now check the RPQ state                                               */
  440.     /*************************************************************************/
  441.     if ((rpq_state   == RPQ_QUEUED)        &&
  442.         (write_state != WRITE_OUTSTANDING) &&
  443.         (read_state  != RSP_OUTSTANDING)   &&
  444.         (read_state  != RSP_QUEUED))
  445.     {
  446.       /***********************************************************************/
  447.       /* We have an RPQ queued up.  Try to send it                           */
  448.       /***********************************************************************/
  449.       rpq_ok = issue_rpq ();
  450.       if (rpq_ok)
  451.       {
  452.         /*********************************************************************/
  453.         /* If verb completes async change state to indicate this o.w.  call  */
  454.         /* the verb done processor                                           */
  455.         /*********************************************************************/
  456.         if (rpq_verb.common.lua_flag2.async)
  457.         {
  458.           rpq_state = WRITE_OUTSTANDING;
  459.         }
  460.         else
  461.         {
  462.           other_done (&rpq_verb);
  463.           write_state = NO_RPQ;
  464.         }
  465.       }
  466.     }
  467.     else if (rpq_state == RPQ_OUTSTANDING)
  468.     {
  469.       /***********************************************************************/
  470.       /* Check for verb completion                                           */
  471.       /***********************************************************************/
  472.       verb_complete = check_verb_complete (&rpq_verb);
  473.       if (verb_complete)
  474.       {
  475.         other_done (&rpq_verb);
  476.         rpq_state = NO_RPQ;
  477.       }
  478.     }
  479.     /*************************************************************************/
  480.     /* Now check on read verbs                                               */
  481.     /*************************************************************************/
  482.     if (read_state == NO_READ)
  483.     {
  484.       issue_read ();
  485.       if (read_verb.common.lua_flag2.async)
  486.       {
  487.         read_state = READ_OUTSTANDING;
  488.       }
  489.       else
  490.       {
  491.         /*********************************************************************/
  492.         /* read_done will change read_state to RESPONSE_QUEUED or NO_READ    */
  493.         /*********************************************************************/
  494.         read_done (&read_verb);
  495.       }
  496.     }
  497.     else if (read_state == READ_OUTSTANDING)
  498.     {
  499.       verb_complete = check_verb_complete (&read_verb);
  500.       if (verb_complete)
  501.       {
  502.         /*********************************************************************/
  503.         /* read_done will change read_state to RESPONSE_QUEUED or NO_READ    */
  504.         /*********************************************************************/
  505.         read_done (&read_verb);
  506.       }
  507.     }
  508.     else if (read_state == RSP_QUEUED)
  509.     {
  510.       /***********************************************************************/
  511.       /* We need to respond to a message read.  Do a write if one is         */
  512.       /* availible.                                                          */
  513.       /***********************************************************************/
  514.       if (write_state != WRITE_OUTSTANDING)
  515.       {
  516.         /*********************************************************************/
  517.         /* The response is issued using the read_verb                        */
  518.         /*********************************************************************/
  519.         issue_rsp (sense);
  520.         if (read_verb.common.lua_flag2.async)
  521.         {
  522.           read_state = RSP_OUTSTANDING;
  523.         }
  524.         else
  525.         {
  526.           rsp_done (&read_verb);
  527.           read_state = NO_READ;
  528.         }
  529.       }
  530.     }
  531.     else if (read_state == RSP_OUTSTANDING)
  532.     {
  533.       /***********************************************************************/
  534.       /* Check to see if the response is complete                            */
  535.       /***********************************************************************/
  536.       verb_complete = check_verb_complete (&read_verb);
  537.       if (verb_complete)
  538.       {
  539.         rsp_done (&read_verb);
  540.         read_state = NO_READ;
  541.       }
  542.     }
  543.     else
  544.     {
  545.       /***********************************************************************/
  546.       /* Invalid state                                                       */
  547.       /***********************************************************************/
  548.       printf("invalid state");
  549.     }
  550.   }  /* while not terminating                                                */
  551.   return(0);
  552. }  /* main ()                                                                */
  553. /**PROC+**********************************************************************/
  554. /* Name:      csv_init                                                       */
  555. /*                                                                           */
  556. /* Purpose:   set up CSV convert verbs                                       */
  557. /*                                                                           */
  558. /* Returns:   void                                                           */
  559. /*                                                                           */
  560. /* Params:    none                                                           */
  561. /*                                                                           */
  562. /* Operation: sets uup two CSV convert verbs, one in each direction.  Only   */
  563. /* the length needs to be set when the verb is called                        */
  564. /**PROC-**********************************************************************/
  565. void csv_init (void)
  566. {
  567.   convert_to_asc.opcode       = SV_CONVERT;
  568.   convert_to_asc.direction    = SV_EBCDIC_TO_ASCII;
  569.   convert_to_asc.char_set     = SV_G;
  570.   convert_to_asc.source       = read_data;
  571.   convert_to_asc.target       = read_data;
  572.   convert_to_ebc.opcode       = SV_CONVERT;
  573.   convert_to_ebc.direction    = SV_ASCII_TO_EBCDIC;
  574.   convert_to_ebc.char_set     = SV_G;
  575.   convert_to_ebc.source       = write_data;
  576.   convert_to_ebc.target       = write_data;
  577. }  /* csv_init                                                               */
  578. /**PROC+**********************************************************************/
  579. /* Name:      issue_verb                                                     */
  580. /*                                                                           */
  581. /* Purpose:   build a verb and send it                                       */
  582. /*                                                                           */
  583. /* Returns:   int - non-zero => verb failed                                  */
  584. /*                                                                           */
  585. /* Params:    IN type - type of verb to issue                                */
  586. /*                                                                           */
  587. /* Operation: Build an INIT or TERM verb and issue it.  Wait for the verb    */
  588. /*            to complete                                                    */
  589. /**PROC-**********************************************************************/
  590. int issue_verb(type)
  591. unsigned int  type;
  592. {
  593.   memset(&other_verb, 0, sizeof(other_verb));
  594.   other_verb.common.lua_verb             = LUA_VERB_RUI;
  595.   other_verb.common.lua_verb_length      = sizeof(other_verb);
  596.   other_verb.common.lua_opcode           = type;
  597.   if (type == LUA_OPCODE_RUI_INIT)
  598.   {
  599.     memcpy(other_verb.common.lua_luname, lu_name, 8);
  600.     other_verb.common.lua_post_handle    = INITPOST;
  601.   }
  602.   else
  603.   {
  604.     other_verb.common.lua_sid            = sid;
  605.     other_verb.common.lua_post_handle    = TERMPOST;
  606.   }
  607.   RUI((LUA_VERB_RECORD FAR *) &other_verb);
  608. #ifdef WIN32
  609.   if (type == LUA_OPCODE_RUI_INIT)
  610.   {
  611.     WinRUIGetLastInitStatus(0, status_event, WLUA_NTFY_EVENT, 0);
  612.   }
  613. #endif
  614.   if (other_verb.common.lua_flag2.async)
  615.   {
  616. #ifdef WIN32
  617.     if (type == LUA_OPCODE_RUI_INIT)
  618.     {
  619.       wait_active_status (&other_verb);
  620.       wait_verb_complete (&other_verb);
  621.     }
  622.     else
  623. #endif
  624.     {
  625.       wait_verb_complete (&other_verb);
  626.     }
  627.   }
  628.   other_done(&other_verb);
  629.   return(other_verb.common.lua_prim_rc != LUA_OK);
  630. }  /* issue_verb                                                             */
  631. /**PROC+**********************************************************************/
  632. /* Name:      issue_read                                                     */
  633. /*                                                                           */
  634. /* Purpose:   build a read verb and send it                                  */
  635. /*                                                                           */
  636. /* Returns:   void                                                           */
  637. /*                                                                           */
  638. /* Params:    none                                                           */
  639. /*                                                                           */
  640. /* Operation: Build a read verb for all flows and issue it                   */
  641. /**PROC-**********************************************************************/
  642. void issue_read (void)
  643. {
  644.   memset(&read_verb, 0, sizeof(read_verb));
  645.   memset(read_data, 0, DATASIZE);
  646.   read_verb.common.lua_verb             = LUA_VERB_RUI;
  647.   read_verb.common.lua_verb_length      = sizeof(read_verb);
  648.   read_verb.common.lua_opcode           = LUA_OPCODE_RUI_READ;
  649.   read_verb.common.lua_sid              = sid;
  650.   read_verb.common.lua_max_length       = DATASIZE;
  651.   read_verb.common.lua_data_ptr         = (char *) read_data;
  652.   read_verb.common.lua_post_handle      = READPOST;
  653.   read_verb.common.lua_flag1.lu_norm    = 1;
  654.   read_verb.common.lua_flag1.lu_exp     = 1;
  655.   read_verb.common.lua_flag1.sscp_norm  = 1;
  656.   read_verb.common.lua_flag1.sscp_exp   = 1;
  657.   RUI((LUA_VERB_RECORD FAR *)&read_verb);
  658. }  /* issue_read                                                             */
  659. /**PROC+**********************************************************************/
  660. /* Name:      other_done                                                     */
  661. /*                                                                           */
  662. /* Purpose:   handle completed init, write or term verb                      */
  663. /*                                                                           */
  664. /* Returns:   void                                                           */
  665. /*                                                                           */
  666. /* Params:    IN verb - completed verb                                       */
  667. /*                                                                           */
  668. /* Operation: write status to he screen                                      */
  669. /**PROC-**********************************************************************/
  670. void other_done(verb)
  671. LUA_VERB_RECORD *verb;
  672. {
  673.   switch (verb->common.lua_opcode)
  674.   {
  675.     case LUA_OPCODE_RUI_INIT:
  676.          if (verb->common.lua_prim_rc == LUA_OK)
  677.          {
  678.            printf("LU activen");
  679.            sid = verb->common.lua_sid;
  680.          }
  681.          else
  682.          {
  683.            printf("INIT failed, (%4.4x, %8.8lx)n",
  684.                   verb->common.lua_prim_rc, verb->common.lua_sec_rc);
  685.          }
  686.          break;
  687.     case LUA_OPCODE_RUI_WRITE:
  688.          if (verb->common.lua_prim_rc != LUA_OK)
  689.          {
  690.            printf("WRITE failed, (%4.4x, %8.8lx)n",
  691.                   verb->common.lua_prim_rc, verb->common.lua_sec_rc);
  692.          }
  693.          break;
  694.     case LUA_OPCODE_RUI_TERM:
  695.          printf("Terminatedn");
  696.          break;
  697.   }
  698. }  /* other_done                                                             */
  699. /**PROC+**********************************************************************/
  700. /* Name:      read_done                                                      */
  701. /*                                                                           */
  702. /* Purpose:   handle completed read verb                                     */
  703. /*                                                                           */
  704. /* Returns:   void                                                           */
  705. /*                                                                           */
  706. /* Params:    IN verb - completed read verb                                  */
  707. /*                                                                           */
  708. /* Operation: If the completed verb contains data, first parse it and then   */
  709. /*            display it.                                                    */
  710. /*            If message is a BIND or an UNBIND, set the LU-LU session state */
  711. /*            accordingly                                                    */
  712. /*            Also check for EB, CD and change session state flags           */
  713. /**PROC-**********************************************************************/
  714. void read_done(verb)
  715. LUA_VERB_RECORD *verb;
  716. {
  717.   int            count;         /* number of bytes of data left to display   */
  718.   unsigned char *data;          /* pointer to next data to display           */
  719.   BOOL           rsp_required = FALSE; /* is a resonse required              */
  720.   sense = 0l;
  721.   if (verb->common.lua_prim_rc == LUA_OK)
  722.   {
  723.     if ((verb->common.lua_message_type == LUA_MESSAGE_TYPE_LU_DATA)   ||
  724.         (verb->common.lua_message_type == LUA_MESSAGE_TYPE_SSCP_DATA))
  725.     {
  726.       if (verb->common.lua_data_length > 0)
  727.       {
  728.         /*********************************************************************/
  729.         /* We now have to parse the data.  For the moment we only look for   */
  730.         /* RPQ requests.                                                     */
  731.         /*********************************************************************/
  732.         parse_data (read_data, (USHORT) (verb->common.lua_data_length));
  733.         /*********************************************************************/
  734.         /* Display outbound SSCP or LU data.                                 */
  735.         /*********************************************************************/
  736.         convert_to_asc.len = (unsigned short) verb->common.lua_data_length;
  737.         ACSSVC_C((LONG)((UCHAR FAR *)&convert_to_asc));
  738.         data  = read_data;
  739.         count = strlen(data);
  740.         while (count > 0)
  741.         {
  742.           if (count <= 80)
  743.           {
  744.             printf("%sn",data);
  745.             count = 0;
  746.           }
  747.           else
  748.           {
  749.             printf("%80.80sn",data);
  750.             count -= 80;
  751.             data  += 80;
  752.           }
  753.         }
  754.       }
  755.       /***********************************************************************/
  756.       /* Set session state.                                                  */
  757.       /***********************************************************************/
  758.       if (verb->common.lua_rh.ebi)
  759.       {
  760.         printf("EBn");
  761.         send_state = BETB;
  762.       }
  763.       else if (verb->common.lua_rh.cdi)
  764.       {
  765.         printf("CDn");
  766.         send_state = SEND;
  767.       }
  768.       else
  769.       {
  770.         send_state = RECV;
  771.       }
  772.     }
  773.     /*************************************************************************/
  774.     /* Handle BIND or UNBIND as a special case.                              */
  775.     /*************************************************************************/
  776.     else if (verb->common.lua_message_type == LUA_MESSAGE_TYPE_BIND)
  777.     {
  778.       if (((read_data[6] & 0x20) == 0x20)  &&      /* Brackets used and BETB */
  779.           ((read_data[7] & 0xF0) == 0x80)  &&      /* HDX-FF, sec con winner */
  780.           ( read_data[14]        == 0x02))         /* LU type 2              */
  781.       {
  782.         printf("BINDn");
  783.         send_state = BETB;
  784.         lu_session = TRUE;
  785.       }
  786.       else
  787.       {
  788.         printf("BIND rejectedn");
  789.         sense = LUA_INVALID_SESSION_PARAMETERS;
  790.       }
  791.     }
  792.     else if (verb->common.lua_message_type == LUA_MESSAGE_TYPE_UNBIND)
  793.     {
  794.       printf("UNBINDn");
  795.       send_state = BETB;
  796.       lu_session = FALSE;
  797.     }
  798.     /*************************************************************************/
  799.     /* Respond to any RQD request.                                           */
  800.     /*************************************************************************/
  801.     if ((verb->common.lua_message_type != LUA_MESSAGE_TYPE_RSP)  &&
  802.         (verb->common.lua_rh.ri == 0))                  /* definite response */
  803.     {
  804.       rsp_required = TRUE;
  805.     }
  806.   }
  807.   else         /* primary rc not OK - read failed - stop now */
  808.   {
  809.     printf("READ ERROR, primary rc = %4.4x, secondary rc = %8.8lxn",
  810.            verb->common.lua_prim_rc, verb->common.lua_sec_rc);
  811.     closedown();
  812.   }
  813.   /***************************************************************************/
  814.   /* Continue processing with either another read or a write positive rsp.   */
  815.   /* (The callback from issuing response will then issue another read) If    */
  816.   /* we've already gone into closedown, stop here                            */
  817.   /***************************************************************************/
  818.   if (!terminating)
  819.   {
  820.     if (rsp_required)
  821.     {
  822.       read_state = RSP_QUEUED;
  823.     }
  824.     else
  825.     {
  826.       read_state = NO_READ;
  827.     }
  828.   }
  829. }  /* read_done                                                              */
  830. /**PROC+**********************************************************************/
  831. /* Name:      issue_rsp                                                      */
  832. /*                                                                           */
  833. /* Purpose:   issue a response for a request from the host                   */
  834. /*                                                                           */
  835. /* Returns:   void                                                           */
  836. /*                                                                           */
  837. /* Params:    IN sense - sense code for the response                         */
  838. /*                                                                           */
  839. /* Operation: Build a response and write it out.  Uses the read verb control */
  840. /*            block because it has the necessary information.                */
  841. /*                                                                           */
  842. /**PROC-**********************************************************************/
  843. void issue_rsp(sense)
  844. unsigned long sense;
  845. {
  846.   read_verb.common.lua_opcode           = LUA_OPCODE_RUI_WRITE;
  847.   read_verb.common.lua_max_length       = 0;
  848.   read_verb.common.lua_post_handle      = (ULONG) READPOST;
  849.   read_verb.common.lua_rh.rri           = 1;       /* response             */
  850.   read_verb.common.lua_flag1.lu_norm    = 0;
  851.   read_verb.common.lua_flag1.lu_exp     = 0;
  852.   read_verb.common.lua_flag1.sscp_norm  = 0;
  853.   read_verb.common.lua_flag1.sscp_exp   = 0;
  854.   /***************************************************************************/
  855.   /* If we have been given a sense code this must be a negative response     */
  856.   /***************************************************************************/
  857.   if (sense)
  858.   {
  859.     read_verb.common.lua_data_length      = 4;
  860.     memcpy(read_data, &sense, 4);
  861.     read_verb.common.lua_rh.ri            = 1;       /* negative rsp         */
  862.   }
  863.   else
  864.   {
  865.     read_verb.common.lua_data_length      = 0;
  866.     read_verb.common.lua_rh.ri            = 0;       /* positive rsp         */
  867.   }
  868.   /***************************************************************************/
  869.   /* Send the response back on the flow from which the request came          */
  870.   /***************************************************************************/
  871.   if (read_verb.common.lua_flag2.lu_norm)
  872.   {
  873.     read_verb.common.lua_flag1.lu_norm = 1;
  874.   }
  875.   else if (read_verb.common.lua_flag2.lu_exp)
  876.   {
  877.     read_verb.common.lua_flag1.lu_exp = 1;
  878.   }
  879.   else if (read_verb.common.lua_flag2.sscp_norm)
  880.   {
  881.     read_verb.common.lua_flag1.sscp_norm = 1;
  882.   }
  883.   else if (read_verb.common.lua_flag2.sscp_exp)
  884.   {
  885.     read_verb.common.lua_flag1.sscp_exp = 1;
  886.   }
  887.   /***************************************************************************/
  888.   /* Send out the verb                                                       */
  889.   /***************************************************************************/
  890.   RUI((LUA_VERB_RECORD FAR *)&read_verb);              /* write the response */
  891. }  /* issue_rsp                                                              */
  892. /**PROC+**********************************************************************/
  893. /* Name:      rsp_done                                                       */
  894. /*                                                                           */
  895. /* Purpose:   handle completion of RUI_WRITE, when RUI_WRITE has written a   */
  896. /*            response                                                       */
  897. /*                                                                           */
  898. /* Returns:   void                                                           */
  899. /*                                                                           */
  900. /* Params:    IN verb - completed verb                                       */
  901. /*                                                                           */
  902. /* Operation: If verb did not complete OK print a message and terminate      */
  903. /*                                                                           */
  904. /**PROC-**********************************************************************/
  905. void rsp_done (verb)
  906. LUA_VERB_RECORD *verb;
  907. {
  908.   if (verb->common.lua_prim_rc != LUA_OK)   /* failed to write the response */
  909.   {                                         /* so stop here                 */
  910.     printf("WRITE for response failed, (%4.4x, %8.8lx)n",
  911.             verb->common.lua_prim_rc, verb->common.lua_sec_rc);
  912.     closedown();
  913.   }
  914. }  /* rsp_done                                                               */
  915. /**PROC+**********************************************************************/
  916. /* Name:      closedown                                                      */
  917. /*                                                                           */
  918. /* Purpose:   terminate the application cleanly                              */
  919. /*                                                                           */
  920. /* Returns:   void                                                           */
  921. /*                                                                           */
  922. /* Params:    none                                                           */
  923. /*                                                                           */
  924. /* Operation: Issue an RUI_TERM and wait for it to complete.  Then exit      */
  925. /*                                                                           */
  926. /**PROC-**********************************************************************/
  927. void closedown (void)
  928. {
  929.   if (!terminating)                /* check we haven't already got here from */
  930.   {                                /* another section of the code            */
  931.     terminating = TRUE;            /* then make sure we can't get here again */
  932.     printf("Closedownn");
  933.     if (issue_verb((unsigned int) LUA_OPCODE_RUI_TERM))
  934.     {
  935.       exit(1);
  936.     }
  937.     exit(0);
  938.   }
  939. }  /* closedown                                                              */
  940. /**PROC+**********************************************************************/
  941. /* Name:      check_verb_complete                                            */
  942. /*                                                                           */
  943. /* Purpose:   check for asynchronous verb completion                         */
  944. /*                                                                           */
  945. /* Returns:   BOOL - TRUE => verb has completed                              */
  946. /*                                                                           */
  947. /* Params:    IN - verb - pointer to verb control block                      */
  948. /*                                                                           */
  949. /* Operation: OS specific                                                    */
  950. /*                                                                           */
  951. /**PROC-**********************************************************************/
  952. BOOL check_verb_complete (verb)
  953. LUA_VERB_RECORD * verb;
  954. {
  955. #ifdef DOS5
  956.   /***************************************************************************/
  957.   /* OS/2 case.  The verb is complete when the semaphore is cleared          */
  958.   /***************************************************************************/
  959.   USHORT RetCode;                     /* Holds return code from OS calls     */
  960.   BOOL   verb_complete;               /* Has the verb completed              */
  961.   verb_complete = FALSE;
  962.   RetCode = DosSemRequest ((HSEM) verb->common.lua_post_handle, 0l);
  963.   if (RetCode != NO_ERROR)
  964.   {
  965.     if (RetCode != ERROR_SEM_TIMEOUT)
  966.     {
  967.       /***********************************************************************/
  968.       /* If we get here we've got problems                                   */
  969.       /***********************************************************************/
  970.       printf("Bad DosSemRequest return code, %d", RetCode);
  971.     }
  972.   }
  973.   else
  974.   {
  975.     verb_complete = TRUE;
  976.     set_semaphore (verb);
  977.   }
  978.   return(verb_complete);
  979. #endif
  980. #ifdef PDOS
  981.   /***************************************************************************/
  982.   /* DOS case.  The verb is complete when the lua_post_handle is cleared     */
  983.   /***************************************************************************/
  984.   BOOL   verb_complete;               /* Has the verb completed              */
  985.   verb_complete = FALSE;
  986.   if (!verb->common.lua_post_handle)
  987.   {
  988.     verb_complete = TRUE;
  989.     set_semaphore (verb);
  990.   }
  991.   return(verb_complete);
  992. #endif
  993. #ifdef WIN32
  994.   /***************************************************************************/
  995.   /* Win32 case.  The verb is complete when the semaphore is cleared         */
  996.   /***************************************************************************/
  997.   DWORD  RetCode;
  998.   RetCode = WaitForSingleObject((HANDLE) verb->common.lua_post_handle, 0l);
  999.   if (RetCode == 0)
  1000.   {
  1001.     set_semaphore (verb);
  1002.   }
  1003.   return((RetCode == 0));
  1004. #endif
  1005. }  /* check_verb_complete                                                    */
  1006. #ifdef WIN32
  1007. /**PROC+**********************************************************************/
  1008. /* Name:      wait_active_status                                             */
  1009. /*                                                                           */
  1010. /* Purpose:   waits for status to become active                              */
  1011. /*                                                                           */
  1012. /* Returns:   void                                                           */
  1013. /*                                                                           */
  1014. /* Operation:                                                                */
  1015. /*                                                                           */
  1016. /**PROC-**********************************************************************/
  1017. void wait_active_status(verb)
  1018. LUA_VERB_RECORD * verb ;
  1019. {
  1020.   DWORD RetCode;
  1021.   DWORD Status = 0;
  1022.   char status_buff[80];
  1023.   while (Status != WLUALUACTIVE)
  1024.   {
  1025.     RetCode = WaitForSingleObject(status_event,(DWORD)-1);
  1026.     Status = WinRUIGetLastInitStatus(verb->common.lua_sid, NULL, WLUA_NTFY_EVENT, 0);
  1027.     GetFmiReturnCode((unsigned short)Status,(unsigned short) 0xffff,(unsigned short) 80, status_buff);
  1028.     printf("%sn",status_buff);
  1029.   }
  1030.   printf("LU ACT receivedn");
  1031. }
  1032. #endif
  1033. /**PROC+**********************************************************************/
  1034. /* Name:      wait_verb_complete                                             */
  1035. /*                                                                           */
  1036. /* Purpose:   waits for async verb completion                                */
  1037. /*                                                                           */
  1038. /* Returns:   void                                                           */
  1039. /*                                                                           */
  1040. /* Params:    IN - verb - pointer to verb control block                      */
  1041. /*                                                                           */
  1042. /* Operation: Wait for the lua_post_handle to become clear                   */
  1043. /*                                                                           */
  1044. /**PROC-**********************************************************************/
  1045. void wait_verb_complete (verb)
  1046. LUA_VERB_RECORD * verb ;
  1047. {
  1048. #ifdef DOS5
  1049.   USHORT RetCode;                     /* Holds return code from OS calls     */
  1050.   RetCode = DosSemRequest ((HSEM)verb->common.lua_post_handle, -1l);
  1051. #endif
  1052. #ifdef PDOS
  1053.   while (verb->common.lua_post_handle);
  1054. #endif
  1055. #ifdef WIN32
  1056.   DWORD RetCode;
  1057.   RetCode = WaitForSingleObject((HANDLE)verb->common.lua_post_handle,
  1058.                                                                    (DWORD)-1l);
  1059. #endif
  1060.   set_semaphore (verb);
  1061. }  /* wait_verb_complete                                                     */
  1062. /**PROC+**********************************************************************/
  1063. /* Name:      set_semaphore                                                  */
  1064. /*                                                                           */
  1065. /* Purpose:   sets verb completion flags                                     */
  1066. /*                                                                           */
  1067. /* Returns:   void                                                           */
  1068. /*                                                                           */
  1069. /* Params:    IN - verb - pointer to vcb                                     */
  1070. /*                                                                           */
  1071. /* Operation: set the lua_post_handle to the non-signaled state              */
  1072. /*                                                                           */
  1073. /**PROC-**********************************************************************/
  1074. void set_semaphore (verb)
  1075. LUA_VERB_RECORD * verb;
  1076. {
  1077. #ifdef DOS5
  1078.   USHORT RetCode;
  1079.   RetCode = DosSemSet ((HSEM)verb->common.lua_post_handle);
  1080. #endif
  1081. #ifdef PDOS
  1082.   /***************************************************************************/
  1083.   /* Dos Case.  Set lua_post_handle to 1                                     */
  1084.   /***************************************************************************/
  1085.   verb->common.lua_post_handle = 1l;
  1086. #endif
  1087. #ifdef WIN32
  1088.   /*W32***********************************************************************/
  1089.   /*W32* Win 32 case.  Clear the event                                       */
  1090.   /*W32***********************************************************************/
  1091.   ResetEvent ((HANDLE) verb->common.lua_post_handle);
  1092. #endif
  1093. }  /* set_semaphore                                                          */
  1094. /**PROC+**********************************************************************/
  1095. /* Name:      do_keyboard_stuff                                              */
  1096. /*                                                                           */
  1097. /* Purpose:   poll keyboard for data                                         */
  1098. /*                                                                           */
  1099. /* Returns:   BOOL - TRUE => we have data to send                            */
  1100. /*                                                                           */
  1101. /* Params:    none                                                           */
  1102. /*                                                                           */
  1103. /* Operation: poll keyboard                                                  */
  1104. /*            if some data                                                   */
  1105. /*              read it in                                                   */
  1106. /*              add it to data buffer                                        */
  1107. /*              if data is <enter>                                           */
  1108. /*                return TRUE                                                */
  1109. /*              endif                                                        */
  1110. /*            endif                                                          */
  1111. /*            return false                                                   */
  1112. /*                                                                           */
  1113. /* Also keep track of which session is being used, and if user wishes to     */
  1114. /* exit.                                                                     */
  1115. /*                                                                           */
  1116. /**PROC-**********************************************************************/
  1117. BOOL do_keyboard_stuff (void)
  1118. {
  1119.   BOOL   data_to_send;             /* do we have data to send?               */
  1120.   INT    input_char;               /* an input character                     */
  1121. #ifdef WIN32
  1122.   INPUT_RECORD input_record;       /* input record                           */
  1123.   DWORD        no_read;            /* number of input records read           */
  1124. #endif
  1125.   data_to_send = FALSE;
  1126.   /***************************************************************************/
  1127.   /* Check if keyboard has been hit                                          */
  1128.   /***************************************************************************/
  1129. #ifdef WIN32
  1130.   while ((!data_to_send) &&
  1131.          (!terminating)  &&
  1132.          (PeekConsoleInput (std_input, &input_record, 1, &no_read)) &&
  1133.          (no_read > 0))
  1134. #else
  1135.   while ((!data_to_send) && (!terminating) && (kbhit()))
  1136. #endif
  1137.   {
  1138. #ifndef WIN32
  1139.     input_char = getch();
  1140.     if ((input_char == 0) || (input_char == 0xE0))
  1141. #else
  1142.     ReadConsoleInput (std_input, &input_record, 1, &no_read);
  1143.     if ((input_record.EventType == KEY_EVENT) &&
  1144.         (input_record.Event.KeyEvent.bKeyDown) &&
  1145.         ((input_record.Event.KeyEvent.dwControlKeyState == LEFT_ALT_PRESSED) ||
  1146.          ((input_record.Event.KeyEvent.wVirtualKeyCode >= VK_F1 ) &&
  1147.           (input_record.Event.KeyEvent.wVirtualKeyCode <= VK_F24))))
  1148. #endif
  1149.     {
  1150.       /***********************************************************************/
  1151.       /* Not an ascii char                                                   */
  1152.       /***********************************************************************/
  1153. #ifndef WIN32
  1154.       input_char = getch ();
  1155. #endif
  1156.       /***********************************************************************/
  1157.       /* Check for function keys and ALT-??                                  */
  1158.       /***********************************************************************/
  1159. #ifndef WIN32
  1160.       if (input_char == 60)               /* F2                              */
  1161. #else
  1162.       if (input_record.Event.KeyEvent.wVirtualKeyCode == VK_F2)
  1163. #endif
  1164.       {
  1165.         /*********************************************************************/
  1166.         /* Send a Clear.                                                     */
  1167.         /*********************************************************************/
  1168.         printf("sending clearn");
  1169.         *write_data = 0x6d;
  1170.         write_len   = 1;
  1171.         data_to_send = TRUE;
  1172.       }
  1173. #ifndef WIN32
  1174.       else if ((input_char >= 120) && (input_char <= 129))
  1175. #else
  1176.       else if ((input_record.Event.KeyEvent.wVirtualKeyCode >= '0') &&
  1177.                (input_record.Event.KeyEvent.wVirtualKeyCode <= '9'))
  1178. #endif
  1179.       {
  1180.         /*********************************************************************/
  1181.         /* ALT-1 to ALT-0                                                    */
  1182.         /* 0xF1 is the AID code for PF1                                                              */
  1183.         /* Follow this with the cursor address                               */
  1184.         /*********************************************************************/
  1185. #ifndef WIN32
  1186.         *write_data = 0xF1 + input_char - 120;
  1187. #else
  1188.         *write_data = 0xF0 + input_record.Event.KeyEvent.wVirtualKeyCode - '0';
  1189. #endif
  1190.         *(write_data + 1) = 0x40;
  1191.         *(write_data + 2) = 0x40;
  1192.         write_len = 3;
  1193.         data_to_send = TRUE;
  1194.       }
  1195.     }
  1196.     else
  1197. #ifdef WIN32
  1198.         if ((input_record.EventType == KEY_EVENT ) &&
  1199.             (input_record.Event.KeyEvent.bKeyDown))
  1200. #endif
  1201.     {
  1202.       /***********************************************************************/
  1203.       /* An ASCII char                                                       */
  1204.       /***********************************************************************/
  1205. #ifdef WIN32
  1206.       input_char = input_record.Event.KeyEvent.uChar.AsciiChar;
  1207. #endif
  1208.       if (input_char == EXITKEY)
  1209.       {
  1210.         closedown();
  1211.       }
  1212.       else if (input_char == SWITKEY)
  1213.       {
  1214.         /*********************************************************************/
  1215.         /* Hit key to switch between sessions                                */
  1216.         /*********************************************************************/
  1217.         if (lu_session)
  1218.         {
  1219.           printf("SSCP sessionn");
  1220.           lu_session = FALSE;
  1221.         }
  1222.         else
  1223.         {
  1224.           printf("LU sessionn");
  1225.           lu_session = TRUE;
  1226.         }
  1227.       }
  1228.       else
  1229.       {
  1230.         /*********************************************************************/
  1231.         /* Key should be real data.  Add it to the string                    */
  1232.         /* For Windows NT echo the character to the screen                   */
  1233.         /*********************************************************************/
  1234.         if (input_char == 13)
  1235.         {
  1236. #ifdef WIN32
  1237.           WriteConsole (std_output, &input_char, 1, &no_read, NULL);
  1238. #endif
  1239.           /*******************************************************************/
  1240.           /* If user pressed return key then send the data.  Reset           */
  1241.           /* data_offset for next data.                                      */
  1242.           /*******************************************************************/
  1243.           write_data[data_offset++] = '';
  1244.           data_to_send = TRUE;
  1245.           data_offset  = 0;
  1246.           /*******************************************************************/
  1247.           /* Convert data to EBCDIC                                          */
  1248.           /*******************************************************************/
  1249.           convert_to_ebc.len = (unsigned short) (strlen(write_data) );
  1250.           if (convert_to_ebc.len > 0)
  1251.           {
  1252.             ACSSVC_C((LONG)((UCHAR FAR *)&convert_to_ebc));
  1253.           }
  1254.           write_len = convert_to_ebc.len;
  1255.           /*******************************************************************/
  1256.           /* Allow for ENTER AID if necessary                                */
  1257.           /*******************************************************************/
  1258.           if (lu_session)
  1259.           {
  1260.             write_data -= WRITE_EXTRA;
  1261.             write_len  += WRITE_EXTRA;
  1262.           }
  1263.         }
  1264.         else if (input_char == 8)
  1265.         {
  1266. #ifdef WIN32
  1267.           WriteConsole (std_output, &input_char, 1, &no_read, NULL);
  1268. #endif
  1269.           /*******************************************************************/
  1270.           /* Backspace.  Delete last char                                    */
  1271.           /*******************************************************************/
  1272.           if (data_offset > 0)
  1273.           {
  1274.             data_offset--;
  1275.           }
  1276.         }
  1277.         else if (input_char != 0)
  1278.         {
  1279. #ifdef WIN32
  1280.           WriteConsole (std_output, &input_char, 1, &no_read, NULL);
  1281. #endif
  1282.           write_data[data_offset++] = (UCHAR) input_char;
  1283.         }
  1284.       }
  1285.     }
  1286.   }  /* if (kbhit())                                                         */
  1287.   return(data_to_send);
  1288. }  /* do_keyboard_stuff                                                      */
  1289. /**PROC+**********************************************************************/
  1290. /* Name:      do_write                                                       */
  1291. /*                                                                           */
  1292. /* Purpose:   issue a write verb                                             */
  1293. /*                                                                           */
  1294. /* Returns:   BOOL - TRUE => data sent OK                                    */
  1295. /*                                                                           */
  1296. /* Params:    none                                                           */
  1297. /*                                                                           */
  1298. /* Operation: convert data to EBCDIC and send it on the right session        */
  1299. /*                                                                           */
  1300. /**PROC-**********************************************************************/
  1301. BOOL do_write (void)
  1302. {
  1303.   BOOL ok;
  1304.   ok = TRUE;
  1305.   /***************************************************************************/
  1306.   /* Set up the vcb                                                          */
  1307.   /***************************************************************************/
  1308.   memset(&other_verb, 0, sizeof(other_verb));
  1309.   other_verb.common.lua_verb             = LUA_VERB_RUI;
  1310.   other_verb.common.lua_verb_length      = sizeof(read_verb);
  1311.   other_verb.common.lua_opcode           = LUA_OPCODE_RUI_WRITE;
  1312.   other_verb.common.lua_sid              = sid;
  1313.   other_verb.common.lua_data_length      = write_len;
  1314.   other_verb.common.lua_data_ptr         = (char far *) write_data;
  1315.   other_verb.common.lua_post_handle      = WRITEPOST;
  1316.   other_verb.common.lua_rh.bci           = 1;
  1317.   other_verb.common.lua_rh.eci           = 1;
  1318.   other_verb.common.lua_rh.dr1i          = 1;
  1319.   if (lu_session)
  1320.   {
  1321.     /*************************************************************************/
  1322.     /* On the LU session we must add the <enter> key prefix.  All inbound    */
  1323.     /* requests flow RQE with the BBI and CDI flags set depending on the     */
  1324.     /* current session state.                                                */
  1325.     /*************************************************************************/
  1326.     other_verb.common.lua_flag1.lu_norm  = 1;
  1327.     other_verb.common.lua_rh.ri          = 1;
  1328.     if (send_state == BETB)
  1329.     {
  1330.       /***********************************************************************/
  1331.       /* Between bracket, so open bracket and give direction.  Note that we  */
  1332.       /* can do this since we will always be contention winner.              */
  1333.       /***********************************************************************/
  1334.       other_verb.common.lua_rh.bbi         = 1;
  1335.       other_verb.common.lua_rh.cdi         = 1;
  1336.       send_state = RECV;
  1337.     }
  1338.     else if (send_state = SEND)
  1339.     {
  1340.       /***********************************************************************/
  1341.       /* In bracket and we have direction, so simply give direction.         */
  1342.       /***********************************************************************/
  1343.       other_verb.common.lua_rh.cdi         = 1;
  1344.       send_state = RECV;
  1345.     }
  1346.     else
  1347.     {
  1348.       /***********************************************************************/
  1349.       /* In bracket and we do not have direction, so do not send.            */
  1350.       /***********************************************************************/
  1351.       printf("Waitn");
  1352.       ok = FALSE;
  1353.     }
  1354.   }
  1355.   else
  1356.   {
  1357.     /*************************************************************************/
  1358.     /* On the SSCP session things are straightforward.                       */
  1359.     /*************************************************************************/
  1360.     other_verb.common.lua_flag1.sscp_norm  = 1;
  1361.   }
  1362.   if (ok)
  1363.   {
  1364.     /*************************************************************************/
  1365.     /* Issue write verb                                                      */
  1366.     /*************************************************************************/
  1367.     RUI((LUA_VERB_RECORD FAR *) &other_verb);
  1368.     /*************************************************************************/
  1369.     /* Reset write_data to point to correct point in write_array             */
  1370.     /*************************************************************************/
  1371.     write_data = write_array + WRITE_EXTRA;
  1372.   }
  1373.   return(ok);
  1374. }  /* do_write ()                                                            */
  1375. /**PROC+**********************************************************************/
  1376. /* Name:      parse_data                                                     */
  1377. /*                                                                           */
  1378. /* Purpose:   parse data from the host                                       */
  1379. /*                                                                           */
  1380. /* Returns:   void                                                           */
  1381. /*                                                                           */
  1382. /* Params:    IN  data - pointer to data                                     */
  1383. /*                                                                           */
  1384. /* Operation: Looks through data for read partition query from host.  Could  */
  1385. /* be expanded to format data from host                                      */
  1386. /*                                                                           */
  1387. /**PROC-**********************************************************************/
  1388. void parse_data (data, length)
  1389. UCHAR FAR * data;
  1390. USHORT      length;
  1391. {
  1392.   USHORT  field_length;
  1393.   switch (*(data++))
  1394.   {
  1395.     case 0xF3:                       /* write structured field               */
  1396.       /***********************************************************************/
  1397.       /* Next byte is the WCC - ignore                                       */
  1398.       /***********************************************************************/
  1399.       data++;
  1400.       length -= 2;
  1401.       while (length > 0)
  1402.       {
  1403.         /*********************************************************************/
  1404.         /* We're just looking for a Read Partion query                       */
  1405.         /*********************************************************************/
  1406.         field_length = (((USHORT) *data) << 8) || ((USHORT) *(data + 1));
  1407.         if ((*(data+2) == 0x01) &&   /* Read partition                       */
  1408.             (*(data+3) == 0xFF) &&   /* Query                                */
  1409.             (*(data+4) == 0x02))     /* not a list                           */
  1410.         {
  1411.           /*******************************************************************/
  1412.           /* Build an RPQ and flag it to be sent                             */
  1413.           /*******************************************************************/
  1414.           rpq_state = RPQ_QUEUED;
  1415.         }
  1416.         data   += field_length;
  1417.         length -= field_length;
  1418.       }
  1419.       break;
  1420.     default:
  1421.       break;
  1422.   }
  1423. }  /* parse_data                                                             */
  1424. /**PROC+**********************************************************************/
  1425. /* Name:      issue_rpq                                                      */
  1426. /*                                                                           */
  1427. /* Purpose:   issue a response to a Read partition query                     */
  1428. /*                                                                           */
  1429. /* Returns:   BOOL - TRUE => sent OK                                         */
  1430. /*                                                                           */
  1431. /* Params:    none                                                           */
  1432. /*                                                                           */
  1433. /* Operation: Builds and sends an RPQ reesponse                              */
  1434. /*                                                                           */
  1435. /**PROC-**********************************************************************/
  1436. BOOL issue_rpq (void)
  1437. {
  1438.   BOOL issue_rpq;
  1439.   issue_rpq = TRUE;
  1440.   /***************************************************************************/
  1441.   /* Set up the vcb                                                          */
  1442.   /***************************************************************************/
  1443.   memset(&rpq_verb, 0, sizeof(rpq_verb));
  1444.   rpq_verb.common.lua_verb             = LUA_VERB_RUI;
  1445.   rpq_verb.common.lua_verb_length      = sizeof(rpq_verb);
  1446.   rpq_verb.common.lua_opcode           = LUA_OPCODE_RUI_WRITE;
  1447.   rpq_verb.common.lua_sid              = sid;
  1448.   rpq_verb.common.lua_data_length      = RPQ_LENGTH;
  1449.   rpq_verb.common.lua_data_ptr         = (char far *) rpq_data;
  1450.   rpq_verb.common.lua_post_handle      = RPQPOST;
  1451.   rpq_verb.common.lua_rh.bci           = 1;
  1452.   rpq_verb.common.lua_rh.eci           = 1;
  1453.   rpq_verb.common.lua_rh.dr1i          = 1;
  1454.   /***************************************************************************/
  1455.   /* On the LU session we must add the <enter> key prefix.  All inbound      */
  1456.   /* requests flow RQE with the BBI and CDI flags set depending on the       */
  1457.   /* current session state.                                                  */
  1458.   /***************************************************************************/
  1459.   rpq_verb.common.lua_flag1.lu_norm  = 1;
  1460.   rpq_verb.common.lua_rh.ri          = 1;
  1461.   if (send_state == BETB)
  1462.   {
  1463.     /*************************************************************************/
  1464.     /* Between bracket, so open bracket and give direction.  Note that we    */
  1465.     /* can do this since we will always be contention winner.                */
  1466.     /*************************************************************************/
  1467.     rpq_verb.common.lua_rh.bbi         = 1;
  1468.     rpq_verb.common.lua_rh.cdi         = 1;
  1469.     send_state = RECV;
  1470.   }
  1471.   else if (send_state = SEND)
  1472.   {
  1473.     /*************************************************************************/
  1474.     /* In bracket and we have direction, so simply give direction.           */
  1475.     /*************************************************************************/
  1476.     rpq_verb.common.lua_rh.cdi         = 1;
  1477.     send_state = RECV;
  1478.   }
  1479.   else
  1480.   {
  1481.     /*************************************************************************/
  1482.     /* In bracket and we do not have direction, so do not send.              */
  1483.     /*************************************************************************/
  1484.     printf("Waitn");
  1485.     issue_rpq = FALSE;
  1486.   }
  1487.   if (issue_rpq)
  1488.   {
  1489.     RUI((LUA_VERB_RECORD FAR *) &rpq_verb);
  1490.   }
  1491.   return(issue_rpq);
  1492. }  /* issue_rpq                                                              */