home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / sna / rui3270 / rui3270.c < prev    next >
C/C++ Source or Header  |  1997-04-09  |  74KB  |  1,666 lines

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