home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: OtherApp / OtherApp.zip / aping.zip / apingd.c < prev    next >
Text File  |  1993-05-10  |  14KB  |  363 lines

  1. /*****************************************************************************
  2.  *
  3.  *  MODULE NAME: APINGD.C
  4.  *
  5.  *  COPYRIGHTS:
  6.  *             This module contains code made available by IBM
  7.  *             Corporation on an AS IS basis.  Any one receiving the
  8.  *             module is considered to be licensed under IBM copyrights
  9.  *             to use the IBM-provided source code in any way he or she
  10.  *             deems fit, including copying it, compiling it, modifying
  11.  *             it, and redistributing it, with or without
  12.  *             modifications.  No license under any IBM patents or
  13.  *             patent applications is to be implied from this copyright
  14.  *             license.
  15.  *
  16.  *             A user of the module should understand that IBM cannot
  17.  *             provide technical support for the module and will not be
  18.  *             responsible for any consequences of use of the program.
  19.  *
  20.  *             Any notices, including this one, are not to be removed
  21.  *             from the module without the prior written consent of
  22.  *             IBM.
  23.  *
  24.  *  AUTHOR:    Peter J. Schwaller
  25.  *             VNET:     PJS at RALVM6           Tie Line: 444-4376
  26.  *             Internet: pjs@ralvm6.vnet.ibm.com     (919) 254-4376
  27.  *
  28.  *  FUNCTION:  Perform an echo test to a specified LU.
  29.  *             APING can be used when you are first installing APPC on
  30.  *             your computer to make sure you can connect to another
  31.  *             computer in the network.  APING can also be used to
  32.  *             get an estimate of the delay time or throughput to another
  33.  *             computer in the network.
  34.  *
  35.  *             APINGD echos whatever is sent by APING.
  36.  *                Keep receiving until you get permission to send
  37.  *                Send the same number of same size records
  38.  *
  39.  *  AVAILABILITY:
  40.  *             These sample programs and source are also available on
  41.  *             CompuServe through the APPC Information Exchange.  To get
  42.  *             to the APPC forum just type 'GO APPC' from any CompuServe
  43.  *             prompt.  The samples are available in the Sample Programs
  44.  *             library section.  Just search on the keyword CPICPGMS to
  45.  *             find all the samples in this series.
  46.  *
  47.  *             Updates for the sample programs and support for many more
  48.  *             CPI-C platforms will also be made available on CompuServe.
  49.  *
  50.  *  RELATED FILES:
  51.  *             See APING.DOC for usage instructions.
  52.  *
  53.  *  PORTABILIITY NOTES:
  54.  *             The APINGD server program is completely portable.  In fact,
  55.  *             all of the source modules can be compiled without #define-ing
  56.  *             any platform constant value.
  57.  *
  58.  *             To take advantage of a performance optimization on the
  59.  *             OS/2 platform, the alloc_cpic_buffer() is used.  If the
  60.  *             OS/2 platform is specified (#define of OS2, FAPI, or OS2_20)
  61.  *             alloc_cpic_buffer() will return a shared memory buffer.
  62.  *             If not, a buffer allocated with malloc() will be returned.
  63.  *
  64.  *             If you are porting to a platform that can take advantage
  65.  *             of a specially allocated memory buffer, you should
  66.  *             add this support to the alloc_cpic_buffer() call in the
  67.  *             CPICPORT.C file.
  68.  *
  69.  *  CHANGE HISTORY:
  70.  *  Date       Description
  71.  *  06/15/92   NS/DOS accepts version 2.02 into system test.
  72.  *  08/05/92   Version 2.31 released to CompuServe
  73.  *             This version was also distributed at the APPC/APPN Platform
  74.  *             Developer's Conference held in Raleigh, NC.
  75.  *  08/13/92   Changed all printf and fprintf calls to use a write_*() call.
  76.  *  08/24/92   Version 2.32 released to CompuServe.
  77.  *  09/22/92   Version 2.33 released to CompuServe.
  78.  *  11/17/92   Supports sending operating system string - see CPICERR.C
  79.  *             Version 2.34 released to CompuServe
  80.  *  01/07/93   Version 2.35
  81.  *             Fixed a number of problems when compiling with IBM C Set/2
  82.  *                password input was displayed
  83.  *                timer resolution was 1 second
  84.  *  03/29/93   Version 2.36
  85.  *                fixed problems when compiling for MVS
  86.  *                  was looking for CPI-C security values
  87.  *  05/06/93   Version 2.37
  88.  *                Added a higher resolution timer for VM
  89.  *
  90.  *****************************************************************************/
  91.  
  92.  
  93. /* My CPI-C include file */
  94. /* Hides CMC.H differences among platforms */
  95. #include "cpiccmc.h"
  96.  
  97. /* standard C include files */
  98. #include <stdio.h>
  99. #include <stdlib.h>
  100. #include <string.h>
  101.  
  102. /* Set up constant declarations */
  103. #include "cpicdefs.h"
  104.  
  105. /* Collection of routines with special ported version for each platform */
  106. #include "cpicport.h"
  107.  
  108. /* CPI-C error handling routines */
  109. /* This file is supplied with APINGD */
  110. #include "cpicerr.h"
  111.  
  112. /* CPI-C initialization routines */
  113. /* This file is supplied with APINGD */
  114. #include "cpicinit.h"
  115.  
  116. /* Argument processing procedure */
  117. /* This file is supplied with APINGD */
  118. #include "getopt.h"
  119.  
  120. /* CPI-C error handling info */
  121. CPICERR * cpicerr;
  122.  
  123. /*
  124.  * Max size of a data buffer.  This is the largest size buffer that can
  125.  * be specified on a call to CPI-C.
  126.  */
  127. #define  MAX_SIZE (0x7FFF)
  128.  
  129. /* Define these here so we can make changes throughout the code. */
  130. /*
  131.  * The PROGRAM_INFO string should be kept in sync with the
  132.  * MAJOR_VERSION and MINOR_VERSION constants.  Although the
  133.  * cpicerr_exchange_version() call will support values up to 255,
  134.  * values for MINOR_VERSION should be from 00-99 to maintain the
  135.  * two character format in the version string.
  136.  */
  137. #define  PROGRAM_NAME      "APINGD"
  138. #define  PROGRAM_INFO      "version 2.37"
  139. #define  MAJOR_VERSION     (2)
  140. #define  MINOR_VERSION     (37)
  141. #define  LOG_FILE_NAME     "apingd.err"
  142. #define  LOG_FILE_PATH     "$LOGPATH"
  143.  
  144. /*
  145.  * Message displayed with show_info() when APINGD is started.
  146.  */
  147. char * intro[] = {
  148.     PROGRAM_NAME " " PROGRAM_INFO " - APPC loopback server",
  149.     NULL
  150.     };
  151.  
  152. char * log_file_name = NULL;
  153.  
  154.  
  155. void
  156. main( int argc, char *argv[])
  157. {
  158.     /* Variables used for CPI-C calls */
  159.     unsigned char cm_conv_id[8];            /* CPI-C conversation ID         */
  160.     CM_INT32    cm_rc;                      /* CPI-C return code             */
  161.     CM_INT32    length;                     /* generic length variable       */
  162.     CM_INT32    rts_received;               /* request to send received      */
  163.     CM_INT32    max_receive_len;            /* Max receive length on CMRCV   */
  164.     CM_INT32    data_received;              /* Data received parm from CMRCV */
  165.     CM_INT32    received_len;               /* Amount of data rcvd on CMRCV  */
  166.     CM_INT32    status_received;            /* Status from CMRCV             */
  167.  
  168.     /* Data buffer for send and receive */
  169.     unsigned char CM_PTR buffer;            /* CPIC data buffer              */
  170.  
  171.     char        destination[MAX_DESTINATION];/* Partner destination          */
  172.     unsigned int max_size;                  /* size to receive               */
  173.     int         c;                          /* flag specifed, used w/getopt  */
  174.  
  175.     char partner_major_version;
  176.     char partner_minor_version;
  177.  
  178.  
  179.     show_info(intro);                       /* display intro information     */
  180.  
  181.     while (optind != argc) {
  182.         c = getopt(argc, argv, "?l:");
  183.         switch (c) {
  184.         case EOF:
  185.             optind++;
  186.             break;
  187.         case 'l':
  188.         case 'L':
  189.             write_output("\nIncoming partner LU names will be logged to: %s\n",
  190.                                                                 optarg);
  191.             log_file_name = optarg;
  192.             break;
  193.         } /* endswitch */
  194.     } /* endwhile */
  195.  
  196.     /*
  197.      * Initialize the CPICERR structure.  This is done before the CMACCP
  198.      * call so that we can use CPICERR for help with errors on CMACCP.
  199.      * The procedure is in CPICERR.C
  200.      */
  201.     cpicerr = cpicerr_new();
  202.     cpicerr_set_program_name(cpicerr, PROGRAM_NAME);
  203.     cpicerr_set_program_info(cpicerr, PROGRAM_INFO);
  204.     cpicerr_set_major_version(cpicerr, MAJOR_VERSION);
  205.     cpicerr_set_minor_version(cpicerr, MINOR_VERSION);
  206.     cpicerr_set_log_file_name(cpicerr, LOG_FILE_NAME);
  207.     cpicerr_set_log_file_path(cpicerr, LOG_FILE_PATH);
  208.  
  209.     cmaccp(cm_conv_id,                      /* Accept Conversation           */
  210.            &cm_rc);
  211.  
  212.     /*
  213.      * Fill in conversation information for CPI-C error reporting.
  214.      */
  215.     cpicerr_set_conv_id(cpicerr, cm_conv_id);
  216.  
  217.  
  218.     if (cm_rc != CM_OK) {
  219.         cpicerr_handle_rc(cpicerr, MSG_CMACCP, cm_rc);
  220.     } else {
  221.         CM_INT32 pln_length;
  222.         /*
  223.          * Extract the partner LU name and display it.
  224.          */
  225.         cmepln(cm_conv_id,
  226.                (unsigned char *)destination,
  227.                &pln_length,
  228.                &cm_rc );
  229.  
  230.         destination[(int)pln_length] = '\0';
  231.         write_output("\nContacted by partner: %s\n", destination);
  232.  
  233.         if (log_file_name != NULL) {
  234.             FILE * file;
  235.             file = fopen(log_file_name, "a");
  236.             if (file != NULL) {
  237.                 write_log(file, "\nContacted by partner: %s\n", destination);
  238.                 fclose(file);
  239.             }
  240.         }
  241.  
  242.     }
  243.  
  244.  
  245.     {
  246.     CM_PREPARE_TO_RECEIVE_TYPE prep_to_receive = CM_PREP_TO_RECEIVE_FLUSH;
  247.     cmsptr(cm_conv_id,                       /* Set prepare to receive type  */
  248.            &prep_to_receive,
  249.            &cm_rc);
  250.     if (cm_rc != CM_OK) cpicerr_handle_rc(cpicerr, MSG_CMSPTR, cm_rc);
  251.     }
  252.  
  253.  
  254.     max_receive_len = max_size = MAX_SIZE;
  255.  
  256.     buffer = (unsigned char CM_PTR)alloc_cpic_buffer(max_size);
  257.                                             /* allocate a buffer             */
  258.  
  259.     cpicerr_exchange_version(cpicerr,
  260.                              cm_conv_id,
  261.                              CM_RECEIVE_STATE,
  262.                              (unsigned char *)&partner_major_version,
  263.                              (unsigned char *)&partner_minor_version);
  264.  
  265.     do {
  266.         unsigned long count;                /* number of consecutive         */
  267.                                             /* sends or receives             */
  268.         count = 0;                          /* initialize count of recvs     */
  269.         do {
  270.            cmrcv (cm_conv_id,               /* Receive Data                  */
  271.                   buffer,                   /* Data Pointer                  */
  272.                   &max_receive_len,         /* Size of Data Buffer           */
  273.                   &data_received,           /* returned - data received      */
  274.                   &received_len,            /* returned - length of data     */
  275.                   &status_received,         /* returned - status received    */
  276.                   &rts_received,            /* returned - request to send    */
  277.                   &cm_rc);
  278.  
  279.             if (data_received != CM_NO_DATA_RECEIVED) {
  280.                 count++;                    /* keep track of receives        */
  281.             }
  282.         } while ( (status_received != CM_SEND_RECEIVED) &&
  283.                   (status_received != CM_CONFIRM_RECEIVED) &&
  284.                    !cm_rc);
  285.         /*
  286.          * loop until we get permission to send data or until error
  287.          */
  288.  
  289.         if (cm_rc != CM_OK) {
  290.             if (cm_rc == CM_DEALLOCATED_NORMAL) {
  291.                 do_exit(EXIT_SUCCESS);
  292.             } else {
  293.                 cpicerr_handle_rc(cpicerr, MSG_CMRCV, cm_rc);
  294.             }
  295.         }
  296.  
  297.         if (status_received != CM_CONFIRM_RECEIVED) {
  298.             /*
  299.              * count is now equal to the number of data blocks we received
  300.              * now we will send back the same number of data blocks of equal
  301.              * size
  302.              */
  303.             {
  304.             CM_SEND_TYPE send_type = CM_BUFFER_DATA;
  305.             cmsst(cm_conv_id,
  306.                   &send_type,
  307.                   &cm_rc);
  308.             if (cm_rc != CM_OK) cpicerr_handle_rc(cpicerr, MSG_CMSST, cm_rc);
  309.             }
  310.  
  311.                                  /* send back the same number except for one */
  312.             for ( count--; count && !cm_rc; count-- ) {
  313.                 length = received_len;
  314.                 cmsend(cm_conv_id,
  315.                        buffer,
  316.                        &length,
  317.                        &rts_received,
  318.                        &cm_rc);
  319.                 if (cm_rc != CM_OK) {
  320.                     cpicerr_handle_rc(cpicerr, MSG_CMSEND, cm_rc);
  321.                 }
  322.             }
  323.  
  324.             /*
  325.              * Set the send type to do a send and a prepare to receive.
  326.              * This will send both the data and the send permission indicator
  327.              * to our partner all at once.
  328.              */
  329.             {
  330.             CM_SEND_TYPE send_type = CM_SEND_AND_PREP_TO_RECEIVE;
  331.             cmsst(cm_conv_id,
  332.                   &send_type,
  333.                   &cm_rc);
  334.             if (cm_rc != CM_OK) cpicerr_handle_rc(cpicerr, MSG_CMSST, cm_rc);
  335.             }
  336.  
  337.             length = received_len;
  338.             cmsend(cm_conv_id,
  339.                    buffer,
  340.                    &length,
  341.                    &rts_received,
  342.                    &cm_rc);
  343.             if (cm_rc != CM_OK) cpicerr_handle_rc(cpicerr, MSG_CMSEND, cm_rc);
  344.         } else {
  345.             /*
  346.              * The partner has requested one way data transfer only.
  347.              * We'll just issue Confirmed, then go back up to receive
  348.              * more data.
  349.              */
  350.             cmcfmd(cm_conv_id,
  351.                    &cm_rc);
  352.             if (cm_rc != CM_OK) cpicerr_handle_rc(cpicerr, MSG_CMCFMD, cm_rc);
  353.         }
  354.     } while (cm_rc == CM_OK);
  355.  
  356.  
  357.     /* destroy the object we created with cpicerr_new() */
  358.     cpicerr_destroy(cpicerr);
  359.  
  360.     do_exit(EXIT_SUCCESS);
  361. }
  362.  
  363.